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

wuhz89 2013-06-16 03:06:17
现用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);//将托管数据复制到非托管数据

然后具体怎么处理呀!不明白呀,困扰几天了,知道的朋友万分感谢!
...全文
295 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
wuhz89 2013-06-17
  • 打赏
  • 举报
回复
后来我报考了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); 但这样也还是不行!头痛中。。。
wuhz89 2013-06-17
  • 打赏
  • 举报
回复
引用 1 楼 caozhy 的回复:
d1 = sum(ptr); 或者 d1 = sum(a1[0]); 看看。
还是不行啊,第一种方式d1=sum(ptr),ptr是一个Intptr类型的值,sum传递的参数是double类型的值? 第二种方式,直接传递数组的首地址a1【0】,但这样也是一具体的double值,参数要求double数组?
wuhz89 2013-06-16
  • 打赏
  • 举报
回复
谢谢各位朋友的回复!非常感谢!
wanghui0380 2013-06-16
  • 打赏
  • 举报
回复
一般那第一元素的地址传过去就是 所以这里有1楼的2种方式 1.直接 sum(a1[0]); 2.取的inptr以后传递inptr
tcmakebest 2013-06-16
  • 打赏
  • 举报
回复
不同语言传送数组感觉有点问题,你可以尝试如下: 1 添加参数,表示数组大小 2 delphi 修改参数为 var a1:array of double
lizhibin11 2013-06-16
  • 打赏
  • 举报
回复
sum函数增加一个表示数组长度的参数,length(a1)替代为该长度。
threenewbee 2013-06-16
  • 打赏
  • 举报
回复
d1 = sum(ptr); 或者 d1 = sum(a1[0]); 看看。

110,567

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧