Reputation: 78
I have tried to call the C struct from C#, but I failed to make it work. My struct define in C is as follow:
struct GHX{
double output[28];
int val;
};
And a function that I’m using to calculate the output is
__declspec(dllexport) void GHXfunction(
double *XIN, double *parameter,
int mode, int hour, GHX *result)
{
/*...*/
}
In C#, I tried the following method.
[StructLayout(LayoutKind.Sequential)]
public struct GHX
{
[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 28)]
public double[] output;
public int val;
}
[DllImport("GHXDLL.dll", EntryPoint = "GHXfunction",
CallingConvention = CallingConvention.Cdecl)]
public static extern void GHXfunction(
IntPtr XIN, IntPtr parameter, int mode,
int hour , ref GHX result);
So far, I believe that everything is OK, because someone from stackoverflow has the same problem as me. Then, I just test a simple scenario as follow.
static void Main()
{
IntPtr XIN= IntPtr.Zero;
IntPtr Par=IntPtr.Zero;
int mode=1;
int hour=0;
GHX test = new GHX();
GHXfunction(XIN, Par, mode, hour, ref test);
}
It then till me that "Attempted to read or write protected memory. This is often an indication that other memory is corrupt."
Does anyone have idea about it? Thanks.
Edit, I actually don't know how does IntPtr work. So I guessed IntPtr.Zero will return memory location with 0, maybe i was wrong.
In my original C code I call the function like this
double par[42], xin[5];
ptrxin = &xin[0];
ptrpara = &par[0];
struct GHX result;
GHXfunction(ptrxin, ptrpara, 0, 0,result);
I dont know how to call the function in C# with the pointer input. Thanks.
Working code: Basing on Ben's suggestion. I can call the struct in C#.
[StructLayout(LayoutKind.Sequential)]
public struct GHX
{
[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 28)]
public double[] output;
public int val;
}
[DllImport("GHXDLL.dll", EntryPoint = "GHXfunction", CallingConvention = CallingConvention.Cdecl)]
public static extern void GHXfunction(double[] XIN, double[] parameter, int mode, int hour,ref GHX result);
static void Main()
{
double result;
double[] XIN= new double[5];
double[] Par = new double[42];
int mode = 1;
int hour=0;
GHX test = new GHX();
GHXfunction(XIN, Par, mode, hour,ref test);
result = test.output[0];
}
Upvotes: 0
Views: 109
Reputation: 283614
A C type of double*
should be translated as either
ref double
or
double[]
Since your comments say those are arrays, try:
[DllImport("GHXDLL.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void GHXfunction(double[] XIN, double[] parameter, int mode,
int hour , ref GHX result);
P/invoke will take care of pinning the array and passing the address of the first element.
Upvotes: 1