Proper Use of DllImport

Assume that in the Native.dll file there is a C ++ method int NativeMethod(double, double *) . My first attempt to call this method from managed code was (assuming I don't need to specify an entry point)

 [DllImport("Native.dll")] private static extern int NativeMethod(double inD, IntPtr outD); 

Then, to use the DLL, I did

 IntPtr x = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(IntPtr))); NativeMethod(2.0, x); //do stuff with x Marshal.FreeHGlobal(x); //crash 

I would like to understand why this is happening here. My first assumption is that this is a heap problem because the DLL and my application can use a different CRT. But if so, why not call the NativeMethod call? The method returned x, from which I could successfully extract double from.

I can make the import work by passing double by reference

 [DllImport("Native.dll")] private static extern int NativeMethod(double inD, IntPtr outD); 

Why is FreeHGlobal crashing in the first place and what is the recommended way to pass pointers to your own methods? The out keyword might work fine in this situation, but what if I needed to marshal a string? I don’t think I can get around AllocH and FreeH ...

+7
c # dll marshalling pinvoke unmanaged
source share
3 answers

The problem is that the method accepts double* , which is a pointer to double. You are passing a pointer pointing to IntPtr . This is important only if there is a size difference between double (8 bytes) and IntPtr , which has the size of a variable (4 or 8 bytes). You need to select a pointer to double

 IntPtr x = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(double)); 
+5
source share

I may be mistaken in your goal, but it looks like you are making it more difficult than necessary. Just pass it on the link and let me adjust it to take care of it.

 [DllImport("Native.dll")] private static extern int NativeMethod(double inD, ref double outD); double x; x = 1; NativeMethod( 2.0, ref x ); 
+7
source share

I am not an expert, but should not:

 IntPtr x = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(double))); 
+2
source share

All Articles