Reputation: 108512
I'm attempt to call a C++ dll with a struct and function like
struct some_data{
int size,degree,df,order;
double *x,*y,lambda;
};
extern "C"{
__declspec(dllexport) double *some_func(some_data*);
}
from C#:
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
public struct SOME_DATA
{
public int size;
public int degree;
public int df;
public int order;
public System.IntPtr x;
public System.IntPtr y;
public double lambda;
}
[System.Runtime.InteropServices.DllImportAttribute("mydll.dll",EntryPoint="some_func")]
public static extern System.IntPtr some_func(ref SOME_DATA someData);
public IntPtr some_funcCall(){
double[] x = new double[] { 4, 4, 7, 7 };
double[] y = new double[] { 2, 10, 4, 22 };
SOME_DATA someData = new SOME_DATA();
someData.x = Marshal.AllocHGlobal(x.Length * Marshal.SizeOf(typeof(double)));
Marshal.Copy(x, 0, someData.x, x.Length);
someData.y = Marshal.AllocHGlobal(y.Length * Marshal.SizeOf(typeof(double)));
Marshal.Copy(y, 0, someData.y, y.Length);
someData.size = 50;
someData.degree = 3;
someData.df = 50;
someData.order = 4;
someData.lambda = 1;
return some_func(ref someData);
}
I thought I was pretty dang close, but when I run this, the program just quits at the return statement.
Any ideas where I've gone wrong?
Thanks,
Mark
Upvotes: 1
Views: 2151
Reputation: 9575
Seems like you forget to specify calling convention:
[DllImport("mydll.dll", EntryPoint="some_func", CallingConvention=CallingConvention.Cdecl)]
Upvotes: 1
Reputation: 10028
I would recommend a few things beyond what Ariel has suggested.
some_func(ref someData)
statement to its own line before the return
.Marshal.FreeHGlobal
after that line (otherwise, it will be a memory leak).order
is equivalent to the array length, I would go ahead and use that.The only other idea I can suggest is to use double*
in your struct and/or pin the arrays using the fixed
statement.
Upvotes: 0