C#调用C dll 报错:尝试读取或写入受保护的内存

Misslio 2014-10-20 08:57:18
C#调用C写的dll,参数中有一个int型的指针,一运行就报如题的错误,大家帮忙看下问题。其它的参数就忽略不写了哈。
C代码:
extern "C" __declspec(dllexport) int c_func(..., int* outdatalen)
{
.......
*outdatalen = 4; // 假如要返回给C#的值
........
}

C#代码
[DllImport("xxx.dll")]
public static extern unsafe int c_func(..., int* outdatalen);

public unsafe int sql_func(...,ref int outdatalen) //其它参数省略
{
int ret = 0;

int len = outdatalen;
ret = c_func(..., &len); // 调用C dll函数
outdatalen = len;
return ret;
}

代码已经简化,只列出问题部分,望参与讨论或给出解答。先行谢过。
...全文
343 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
Fox_66 2014-10-21
  • 打赏
  • 举报
回复
[DllImport("xxx.dll", CallingConvention = CallingConvention.Cdecl)] public static extern int c_func(..., int* outdatalen); // 去掉unsafe public int sql_func(...,ref int outdatalen) //其它参数省略 去掉unsafe { int ret = 0; int len = outdatalen; ret = c_func(..., ref len); // 调用C dll函数 outdatalen = len; return ret; }
Saleayas 2014-10-21
  • 打赏
  • 举报
回复
[DllImport("xxx.dll")]

 public static extern int sql_func(..., [Out] ref int outdatalen);

Saleayas 2014-10-21
  • 打赏
  • 举报
回复
[DllImport("xxx.dll")]
 public static extern unsafe int sql_func(..., [Out] ref int outdatalen);
Misslio 2014-10-21
  • 打赏
  • 举报
回复
引用 3 楼 u014260236 的回复:
[quote=引用 2 楼 github_22161131 的回复:] 最好不要在C#里用unsafe,托管环境下的unsafe和c++那边还是不一样的。

//你这个C#这边的方法原型应该写成:
[DllImport("xxx.dll")] public static extern int c_func(..., ref int outdatalen);

//调用的时候就是:
int len = 0;
int ret = c_func(..., ref len);
另外要注意的是C++那边的int不是定长的,而C#的int是32位的,对于你这个返回大小的参数,最好用确定32位的int类型。
你说的这个方法也用过,但是同样报错。我再仔细看下把。[/quote] 还是不行,C代码里的参数用int*这个指针类型是没错的吧,这里给指针指向的空间赋值就出错。
Misslio 2014-10-21
  • 打赏
  • 举报
回复
引用 2 楼 github_22161131 的回复:
最好不要在C#里用unsafe,托管环境下的unsafe和c++那边还是不一样的。

//你这个C#这边的方法原型应该写成:
[DllImport("xxx.dll")] public static extern int c_func(..., ref int outdatalen);

//调用的时候就是:
int len = 0;
int ret = c_func(..., ref len);
另外要注意的是C++那边的int不是定长的,而C#的int是32位的,对于你这个返回大小的参数,最好用确定32位的int类型。
你说的这个方法也用过,但是同样报错。我再仔细看下把。
Misslio 2014-10-21
  • 打赏
  • 举报
回复
问题已经解决了。但具体为什么还是有所困惑,对VS的平台不太熟悉。 把C的dll里的这个int*指针形参放在了前面,而不是最后一个,现在最后一个参数只是一个整数。现在代码跟二楼的区别就是参数位置,其他一样。 如果跟形参入栈顺序有关的话,还是有困惑,乜有加__stdcall测试,哪位理解的话可以告知下。
Misslio 2014-10-21
  • 打赏
  • 举报
回复
引用 7 楼 hky227 的回复:
[DllImport("xxx.dll", CallingConvention = CallingConvention.Cdecl)] public static extern int c_func(..., int* outdatalen); // 去掉unsafe public int sql_func(...,ref int outdatalen) //其它参数省略 去掉unsafe { int ret = 0; int len = outdatalen; ret = c_func(..., ref len); // 调用C dll函数 outdatalen = len; return ret; }
使用指针也是可以操作的,只是代码需要加unsafe关键字,编译也要勾选这个选项。
winnowc 2014-10-20
  • 打赏
  • 举报
回复
最好不要在C#里用unsafe,托管环境下的unsafe和c++那边还是不一样的。

//你这个C#这边的方法原型应该写成:
[DllImport("xxx.dll")] public static extern int c_func(..., ref int outdatalen);

//调用的时候就是:
int len = 0;
int ret = c_func(..., ref len);
另外要注意的是C++那边的int不是定长的,而C#的int是32位的,对于你这个返回大小的参数,最好用确定32位的int类型。
zkranzkran 2014-10-20
  • 打赏
  • 举报
回复
谢谢分享!!!!!

110,536

社区成员

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

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

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