C#调用非托管dll,如何把数组作为参数传递进dll?
现用delphi编写一dllfunction sum(a1:array of double):double;stdcall; //用于测试,具体功能并不仅限于求和
var
data:double;
i:integer;
begin
for i:=0 to length(a1)do
begin
data:=data+a1[i];
end;
result:=data;
end;
现在C#调用时,
[DllImport("SUM.dll", EntryPoint = "sum", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
public static extern double sum(double[] x1);
double[] a1 = new double[4];
double d1;
for (i = 0; i <= 3; i++)
{
a1[i] = i + 10;
}
d1 = sum(a1);//报错:尝试读取或写入受保护的内存。这通常指示其他内存已损坏。
return d1;
后来我稍微修改了一下,不传入数组,直接传递一个double值,却能成功。
我在网上查了一下,要使用MarshalAs类先对数组进行封送至非托管内存,
IntPtr ptr = Marshal.AllocHGlobal(a1.Length);//申请非托管内存块(与a1大小一样)
Marshal.Copy(a1,0,ptr,a1.Length);//将托管数据复制到非托管数据
然后具体怎么处理呀!不明白呀,困扰几天了,知道的朋友万分感谢! C#对非托管dll处理 --------------------编程问答-------------------- d1 = sum(ptr);
或者
d1 = sum(a1[0]);
看看。 --------------------编程问答-------------------- sum函数增加一个表示数组长度的参数,length(a1)替代为该长度。 --------------------编程问答-------------------- 不同语言传送数组感觉有点问题,你可以尝试如下:
1 添加参数,表示数组大小
2 delphi 修改参数为 var a1:array of double --------------------编程问答-------------------- 一般那第一元素的地址传过去就是
所以这里有1楼的2种方式
1.直接
sum(a1[0]);
2.取的inptr以后传递inptr --------------------编程问答-------------------- 谢谢各位朋友的回复!非常感谢! --------------------编程问答--------------------
还是不行啊,第一种方式d1=sum(ptr),ptr是一个Intptr类型的值,sum传递的参数是double类型的值?
第二种方式,直接传递数组的首地址a1【0】,但这样也是一具体的double值,参数要求double数组? --------------------编程问答-------------------- 后来我报考了MSDN上数组的默认封送类型,再方法声明时添加【MarshalAs】
[DllImport("SUM.dll", EntryPoint = "sum", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
public static extern double sum(【MarshalAs(UNmanagedType.SafeArray,SafeArraySubType=VarEnum.VT_R8)】 double[] x1);
但这样也还是不行!头痛中。。。
补充:.NET技术 , C#