从c#调用C结构数据
本文关键字:结构 数据 调用 | 更新日期: 2023-09-27 18:11:53
我已经从dev c++制作了一个dll。我想调用这个函数。开发c++代码如下:
//the head file
struct sAdd
{
int* aarr;
int* barr;
int length;
};
DLLIMPORT int AddStruct (struct sAdd*);
//the c file
DLLIMPORT int AddStruct (struct sAdd* sadd)
{//sum the aarr and the barr and return the result.
int sum=0;
int* aarr=sadd->aarr;
int* barr=sadd->barr;
int numArr=sadd->length;
int i;
for(i=0;i<numArr;i++)
sum+=*(aarr+i);
i=0;
for(i=0;i<numArr;i++)
sum+=*(barr+i);
return sum;
}
为了调用AddStruct函数,我需要首先定义一个结构体。
public struct sAdd
{
public int[] a;
public int[] b;
public int length;
}
[DllImport("DllMain.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int AddStruct(ref sAdd sadd);
调用AddStruct函数的代码如下:
sAdd sadd = new sAdd();
sadd.a = new int[4] { 1, 2, 3 ,4};
sadd.b = new int[4] { 1, 2, 3 ,4};
sadd.length=4;
Console.WriteLine("sAdd:" + AddStruct(ref sadd).ToString());
的结果应该是20,但我得到一个37109984或其他一些大数字。因此,我不确定如何更改代码以获得正确的结果。也许我需要使用IntPtr或其他方式??谢谢。
最后,我处理了这个问题。
[StructLayout(LayoutKind.Sequential)]
public struct sAdd
{
public IntPtr a;
public IntPtr b;
public int length;
};
sAdd sadd = new sAdd();
int[] a = new int[4] { 1, 2, 3 ,4};
int[] b = new int[4] { 1, 2, 3 ,4};
sadd.length = 4;
sadd.a = Marshal.UnsafeAddrOfPinnedArrayElement(a, 0);
sadd.b = Marshal.UnsafeAddrOfPinnedArrayElement(b, 0);
Console.WriteLine("sAdd:" + DllMainWrapper.AddStruct(ref sadd).ToString());
你的C代码坏了
当你只有指向第一个元素的指针时,你不能使用sizeof
计算数组的长度。只有当你在作用域中有一个"真正的"数组声明时,你才能这样做。
:
int* aarr=sadd->aarr;
int* barr=sadd->barr;
int numAarr=sizeof(aarr)/sizeof(int);
int numBarr=sizeof(barr)/sizeof(int);
是坏的,numArr
将是一个常量值(1如果你的指针大小与你的整数大小相同,否则可能是2在64位系统与32位int
)。