当前位置:编程学习 > C#/ASP.NET >>

C#调用非托管dll,如何把数组作为参数传递进dll?

现用delphi编写一dll
function 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 --------------------编程问答-------------------- 谢谢各位朋友的回复!非常感谢! --------------------编程问答--------------------
引用 1 楼 caozhy 的回复:
d1 = sum(ptr);

或者
d1 = sum(a1[0]);
看看。


还是不行啊,第一种方式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#
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,