S. Lacy
S. Lacy

Reputation: 51

How do I pinvoke/Marshal a C++ " const uint64_t* " in C#?

I've worked with quite a few unmanaged C++ DLL's in the past, but ran into a type I've never seen before. My first attempts to pinvoke it have ended in explosions. :)

Here is the C++ function signature:

 DLL_EXPORTS int MUSH_ProcessBuffer(uint64_t NumEntries, const uint64_t* AbsTimeNs, const uint64_t* Events);

Both AbsTimeNs and Events are meant to be arrays of unsigned long's that are getting passed in my C# code. NumEntries is the length of the respective arrays.

I've tried both of the following:

[DllImport("mush.dll", CallingConvention = CallingConvention.StdCall)]
public static extern int MUSH_ProcessBuffer(UInt64 NumEntries, ref ulong[] AbsTimeNS, ref ulong[] Events);

[DllImport("mush.dll", CallingConvention = CallingConvention.StdCall)]
public static extern int MUSH_ProcessBuffer(UInt64 NumEntries, ref UInt64[] AbsTimeNS, ref UInt64[] Events);

Neither worked...I get an exception: {"Attempted to read or write protected memory. This is often an indication that other memory is corrupt."} I'm not sure if I have the wrong type or it has to do with the "const" in the function signature or what. In case it's what I am passing in and not the pinvoke itself...here is the C# code:

ulong[] timeArray = absTimes.ToArray();
ulong[] eventArray = events.ToArray();

NativeMethods.MUSH_ProcessBuffer((ulong)absTimes.Count, ref timeArray, ref eventArray);

Upvotes: 1

Views: 847

Answers (1)

huysentruitw
huysentruitw

Reputation: 28111

You need to remove the ref keywords in your method definition.

An array is already passed by reference, adding ref gives you an additional pointer to that reference.

In C, that would be const uint64_t** instead of const uint64_t*.

So:

[DllImport("mush.dll", CallingConvention = CallingConvention.StdCall)]
public static extern int MUSH_ProcessBuffer(ulong NumEntries, ulong[] AbsTimeNS, ulong[] Events);

Upvotes: 4

Related Questions