Reputation: 5262
I'm PInvoking a native C++ DLL. Actually I've done it twice (two different C# programs, two different C++ programs). Both times I create the memory on the C# side. Both times I used fairly complex marshalled structs which I send by ref.
However, one of my programs run just fine.
The other one runs until the native C++ attempts to read a value from the data sent. But then explosion, I'm hit with a read/write protected memory error?
I don't understand how two programs built with the same Visual Studio, can result in one letting me access the memory and the other prohibited.
I've checked settings, both are pretty much identical in project settings?
In the project I'm having problems, I even reduced the data sent to an exactly sized structure like so:
[StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
struct Shared2_s
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 40)]
public byte[] filler2;
//40
}
Upvotes: 0
Views: 327
Reputation: 13897
If you need the Shared2_s instance to have a lifetime longer than just the call to the native method, you'll need to allocate it in unmanaged memory and clean it up again when done.
var pointer = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Shared2_s)));
var inst = new Shared2_s();
Marshal.StructureToPtr(inst, pointer, false);
...
MyNativeMethod(pointer);
...
Marshal.FreeHGlobal(pointer);
The DllImport declaration of MyNativeMethod should be adjusted so that instead of taking a ref Shared2_s
parameter, it takes an IntPtr
instead.
You should only call FreeHGlobal after you are certain that no other native code will attempt to access the allocated memory.
Upvotes: 1
Reputation: 70369
For this kind of stuff I use a MemoryMappedFile
and a named Mutex
- no marshalling involved, just some bytes in memory which can be read/written to by anyone with the correct permissions and knowledge of the name of the MemoryMappedFile .
[EDIT] For the C++ side of this see the MSDN example here. [/EDIT]
Upvotes: 0