c#调用delphi编写的DLL文件报错,尝试读取或写入受保护的内存.

woxiangbo 2011-07-06 10:51:43
这个问题比较诡异,我在网上搜了很久都没找到答案,
C#调用DELPHI写的DLL,调用其中一个方法:


public static string 显示柜台返回信息()
{

StringBuilder pDataBack = new StringBuilder();
pDataBack.Capacity = 300000;
readAnswer(ThreadNo, UniNumber, dwCommObj, ref pDataBack);
string temp = pDataBack.ToString();

return temp;

}

其中 readAnswer(ThreadNo, UniNumber, dwCommObj, ref pDataBack);
是调用delphi编写的DLL文件里的接口,其中 pDataBack 是在调用之后回写的参数,也就是说在DLL里会对该参数重新赋值,现在问题是,如果赋值的字符比较小,则正常通过,如果赋值的内容过多,则会报错,如下:


未处理的异常: System.AccessViolationException: 尝试读取或写入受保护的内存。这通
常指示其他内存已损坏。
在 SingleFunctionBetter.ReadAnswer.Invoke(Int32 ThreadNo, Int32 UniNumber, In
t32 dwCommObj, StringBuilder& pDataBack)
在 SingleFunctionBetter.Fixture.显示柜台返回信息() 位置 C:\guangda\test\Fixtu
re.cs:行号 111
在 SingleFunctionBetter.Fixture.Main(String[] args) 位置 C:\guangda\test\Fixt
ure.cs:行号 249
请按任意键继续. . .



我把 ref 改成 out也不行,我给pDataBack设置容量 pDataBack.Capacity = 300000;也不行,返回字符肯定小于3万
实在没招了~,在此发帖给大家,希望帮我解决一下,感激不尽~!
...全文
482 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
woxiangbo 2011-07-07
  • 打赏
  • 举报
回复
这个问题还没解决,而且我再 windows 2003 上执行有问题,拷贝到我的win7上也没问题,windows2003 内存4G,我WIN7内存2G。。哎,无语了
woxiangbo 2011-07-06
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 ch_fb 的回复:]
都导出类型 pchar 了,明显 dll 作者已经处理成 C 接口了。
关键 C# 这边难道不该这样吗?

C# code

byte* pDataBack=stackalloc byte[3000];
[/Quote]

可是这个需要回写噢~,回写用byte可以吗 ?还要加关键字 ref 噢
自由建客 2011-07-06
  • 打赏
  • 举报
回复
都导出类型 pchar 了,明显 dll 作者已经处理成 C 接口了。
关键 C# 这边难道不该这样吗?
byte* pDataBack=stackalloc byte[3000];
老毕 2011-07-06
  • 打赏
  • 举报
回复
问题多半出在pchar。

以前DOS版下的Pascal(Delphi的前身),搞过一段时间的C、汇编与Pascal的混合编程,记得pascal规范里,字符串的第一个字节是字符串长度。不知道pchar是不是也这样的。

你可以去Delphi版块去问问,如何把pchar类型转换为适当的.NET Framework类型。
woxiangbo 2011-07-06
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 bdmh 的回复:]
原型是什么
[/Quote]

DELPHI中函数的原型是:
函数原型:function ReadAnswer (ThreadNo: integer; UniNumber: integer; dwCommObj: DWORD; var pDataBack: pchar): boolean;stdcall;

这个DLL是别的公司写的,我不知道源代码,只有接口说明书
bdmh 2011-07-06
  • 打赏
  • 举报
回复
原型是什么
JonnySun 2011-07-06
  • 打赏
  • 举报
回复
C#调用Delphi编译的DLL函数库返回大文本数据|C/S框架网|C# C/S框...

http://www.csframework.com/archive/2/arc-2-20110324-1226.htm
自由建客 2011-07-06
  • 打赏
  • 举报
回复
这里,指针应当去掉 ref !
readAnswer(ThreadNo, UniNumber, dwCommObj, pDataBack);

jidiche 2011-07-06
  • 打赏
  • 举报
回复
DELPHI中函数的原型是:
函数原型:function ReadAnswer (ThreadNo: integer; UniNumber: integer; dwCommObj: DWORD; var pDataBack: pchar): boolean;stdcall;
[Quote=引用 2 楼 woxiangbo 的回复:]
引用 1 楼 bdmh 的回复:
原型是什么


DELPHI中函数的原型是:
函数原型:function ReadAnswer (ThreadNo: integer; UniNumber: integer; dwCommObj: DWORD; var pDataBack: pchar): boolean;stdcall;

这个DLL是别的公司写的,我不知道源代码,只有接口说明书……
[/Quote]
flyerwing 2011-07-06
  • 打赏
  • 举报
回复
试下这样

bool readAnswer(int ThreadNo, int UniNumber, uint dwCommObj,string pDataBack);
woxiangbo 2011-07-06
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 ch_fb 的回复:]
C# code

// 忘了 C# 的栈空间很小,当然,你那个错误提示并非栈溢出。
// 干脆改用这样试试
byte[] DataBack=new byte[30000];
fixed (byte* pDataBack=DataBack) {
readAnswer(ThreadNo, UniNumber, dwCommObj, ref pDataBack);
}

// ……
[/Quote]

我这样写还是报同样的错误。。。
悲剧了。。我用C++调用就没问题,
可以手动设置C#的栈大小吗?
有QQ吗,能否加你QQ请教下,或者加我Q:273040644
自由建客 2011-07-06
  • 打赏
  • 举报
回复
// 忘了 C# 的栈空间很小,当然,你那个错误提示并非栈溢出。
// 干脆改用这样试试
byte[] DataBack=new byte[30000];
fixed (byte* pDataBack=DataBack) {
readAnswer(ThreadNo, UniNumber, dwCommObj, ref pDataBack);
}

// 另外,你这怎么写的?
[DllImport...]
static extern
bool readAnswer(int ThreadNo, int UniNumber, uint dwCommObj, ref byte pDataBack);
woxiangbo 2011-07-06
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 ch_fb 的回复:]
引用 5 楼 woxiangbo 的回复:

引用 4 楼 ch_fb 的回复:
都导出类型 pchar 了,明显 dll 作者已经处理成 C 接口了。
关键 C# 这边难道不该这样吗?

C# code

byte* pDataBack=stackalloc byte[3000];


可是这个需要回写噢~,回写用byte可以吗 ?还要加关键字 ref 噢

字符数组啊……
[/Quote]

我用了,还是报一样的错误。。。说 尝试读取或者写入已保护的内存出错。。
你有QQ吗:我的QQ:273040644
自由建客 2011-07-06
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 woxiangbo 的回复:]

引用 4 楼 ch_fb 的回复:
都导出类型 pchar 了,明显 dll 作者已经处理成 C 接口了。
关键 C# 这边难道不该这样吗?

C# code

byte* pDataBack=stackalloc byte[3000];


可是这个需要回写噢~,回写用byte可以吗 ?还要加关键字 ref 噢
[/Quote]
字符数组啊,有问题吗?
本课程主要是针对ILRuntime设计一个独立的脚本热更新框,框架的优势:1.将代码热更脱离Assetbundle资源热更,独立的部分更适用于各种不同的框架。2.加快项目的逻辑更新,bug修复.(后期修bug,多数情况下并不用动到资源,只需要更新脚本代码,无需重走资源打包发布流程,大大提升效率)3.提供热更模式和正常开发模式的快速切换接口,可以让队友像平常一样去开发.4.不依赖市面上的任何AB框架,完全兼容市面上各种不同的AB框架.5.重点:希望通过它,帮助你学习、了解ILRuntime真正在项目中的应用.框架的将提供以下这些接口,这些接口将从0开始,在Unity里将C#脚本编译成dll,然后将dll放到服务器上,再将dll下载下来,进行加载,到最后从Unity主工程调用热更新的代码逻辑.1.Create hotfixdll接口将热更部分的代码 编译成dll生成dll版本配置(MD5)2.更新对比接口本地跟服务器的dll进行版本对比3.下载热更dll下载dll本身的文件下载版本记录文件4.加载热更dll加载dll实例化:AppDomain初始化:注册跨域继承适配器注册委托适配器LitJson重定向调用性能优化(CLR绑定功能)调用热更接口Hotfix.HotfixApplication.Main 进入热更逻辑5.ILMonoBehaviour用于监听组件的生命周期,实际是桥接(调用)热更的逻辑AwakeStartEnableUpdateLateUpdate.......6.添加其他常用的库DOTweenLitJsonSpineGoogle.ProtobufTextAnimation可以根据上面的方式,自行添加依赖的库... 

110,534

社区成员

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

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

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