0

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
}
0

2 Answers 2

1

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.

Sign up to request clarification or add additional context in comments.

3 Comments

Marshal.StructureToPointer would just copy the data though. I would need the data in the structure to be the SAME memory as the pointer. Is there any way to do this?
Use Marshal.PtrToStructure after the method call to turn it back into the Shared2_s.
I suppose that's no higher cost than having it marshal automatically.
0

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]

2 Comments

it can be that the memory has been garbage collected by GC... which would make run one time and fail another time... or that some locking/pinning has to be done or or... there are countless possibilities and you don't provide enough information to investigate that... that's why I suggested the alternative approach (which is faster) and does not suffer from GC etc.
This is just complicating the issue.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.