Best practice for sharing a structure from a C # program to a C ++ win32 DLL?

What is the best practice of sharing memory structures from a C # program in a C ++ win32 DLL?

I used structures in managed shared memory using Boost between two C ++ programs, and it worked fine. I have lost the best way to accomplish this between where the structure is populated in a C # program and a C ++ DLL, which is a SNMP subagent.

Here's the C ++ DLL:

//==================== Code Excerpt from the main cpp file ====================== #include "stdafx.h" //================= Here we are setting up the shared memory area ===================== #pragma data_seg (".SHAREDMEMORY") struct sharedData { int sharedA; int sharedB; }; static sharedData A; #pragma data_seg() #pragma comment(linker,"/SECTION:.SHAREDMEMORY,RWS") BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { return TRUE; } //============================================================================================= //====================== Here we are writing wrappers to the shared memory area =========================== //=You must declare it as an Extern "C" to prevent name mangling. This is absolutely necessary in order to import it into c# = //============================================================================================= extern "C" __declspec(dllexport) sharedData __stdcall getMyData() { A.sharedA = 1237; A.sharedB = 31337; //return gshared_nTest; return A; } extern "C" __declspec(dllexport) void __stdcall setMyData( sharedData buff ) { A = buff; } 

Here's the calling C # function:

 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Runtime.InteropServices; namespace sharedMemTestCS { public partial class frmSharedMemTestCS : Form { struct sharedData { int sharedA; int sharedB; }; static sharedData A; //============== here we are importing the methods from the win32 dll into the c# console application ================= [DllImport(@"C:\Documents and Settings\My Documents\Visual Studio 2010\Projects\sharedMemTestCPP\Debug\sharedMemTestCPP.dll")] public static extern sharedData getMyData(); [DllImport(@"C:\Documents and Settings\My Documents\Visual Studio 2010\Projects\sharedMemTestCPP\Debug\sharedMemTestCPP.dll")] public static extern void setMyData(int data); public frmSharedMemTestCS() { InitializeComponent(); //============== here i am incrementing the value ================= //== i use a message box so that i can have multiple console applications running at once and it will pause at the messagebox (if i don't click ok) //== i do this so i can see the values changing in the shared memory. //MessageBox.Show( getMyData().ToString() ); getMyData(); //txtBoxA.Text = (getMyData().ToString() ); } private void btnAdd_Click(object sender, EventArgs e) { //setMyData( getMyData() + 100 ); //txtBoxA.Text = (getMyData().ToString() ); } } } 

The error message I get is:

 Error 1 Inconsistent accessibility: return type 

'sharedMemTestCS.frmSharedMemTestCS.sharedData' is less accessible than the method 'sharedMemTestCS.frmSharedMemTestCS.getMyData ()' c: \ documents and settings \ mconrad \ my documents \ visual studio 2010 \ Projects \ sharedMemTestCS \ sharedMemTestCS \ Form1.cs 23

+4
source share
3 answers

The best practice for sharing memory would be to use the MemoryMappedFile class in C # and CreateFileMapping / MapViewOfFile in C ++.

+2
source

Firstly, you cannot use Boost to exchange data. You need to have clearly defined data structures that you have between managed and unmanaged worlds.

You can start here

+2
source

Well, your actual problem is that your p / invoke expression is public, but your structure is private, which tells you the error. If you create a p / invoke private or public public public expression, you will solve the immediate problem.

Regarding the actual exchange of data, I never tried to do it this way, so I can’t tell you whether this will work or not. All the parts I worked with are sorted back and forth. Looking at your sample code, it's possible that it can work. You will probably want to either copy the data into a new structure for C #, or bind the structure you get so that the GC does not move it in memory.

+2
source

All Articles