当前位置: 首页 > 编程语言 > C#

访问DelphiDLL抛出异常异常分享

时间:2023-04-10 22:58:21 C#

访问DelphiDLL抛出ExceptionException当我调用一个Dll方法时,有时会抛出异常,有时不会。我这样称呼它:publicclassDllTest{[DllImport(@"MyDll.dll")]publicexternstaticstringMyMethod(stringsomeStringParam);}classProgram{staticvoidMain(string[]args){DllTest.MyMethod("SomeString");我有时会遇到的异常是:AccessViolationException尝试读取或写入受保护的内存。这通常表示其他内存已损坏。有谁知道为什么我有时会得到这个例外?为什么有时会很顺利?您的p/invoke代码和Delphi代码之间显然不匹配。您没有显示Delphi代码,但C#代码足以知道Delphi代码应该是什么样子。您的DllImport属性使用默认值调用约定和字符集。这意味着调用约定是stdcall,字符集是ANSI。您尚未指定任何编组属性,因此必须使用默认编组。所以您的Delphi代码必须如下所示:functionMyMethod(someStringParam:PChar):PChar;标准调用;开始结果:=??;结尾;现在这就是问题所在。p/invokemarshaller以一种非常特殊的方式处理字符串返回值。它假定p/invoke编组器负责为返回值释放内存。它必须使用与本机代码相同的分配器。编组器假定将使用共享的COM分配器。所以规则是本机代码必须通过调用CoTaskMemAlloc为COM分配器分配内存。我敢打赌你的代码不会这样做,它肯定会导致错误。下面是一个示例,说明如何在代码中创建本机Delphi函数以用于C#签名。函数MyMethod(someStringParam:PChar):PChar;标准调用;变量大小:整数;beginSize:=SizeOf(Char)*(StrLen(someStringParam)+1);//+1用于零终止符Result:=CoTaskMemAlloc(Size);移动(someStringParam^,结果^,大小);结尾;虽然您可以采用这种方法,但我推荐另一种方法。BSTR所有字符串在C#端为BSTR,在Delphi端为WideString。这些是匹配类型,也是由COM分配器分配的。双方都知道如何处理这些类型,会让您的生活更轻松。不幸的是,您不能跨互操作边界从Delphi函数返回WideString,因为Delphi对函数返回值使用不同的ABI。有关此问题的更多详细信息,请参阅我的问题Whycan'tWideStringbeusedasafunctionreturnvalueforinterop?所以,为了解决这个问题,我们可以在Delphi代码中声明返回类型为TBStr。你的代码看起来像这样:delphi函数MyMethod(someStringParam:WideString):TBStr;标准调用;开始结果:=SysAllocString(POleStr(someStringParam));结尾;对我来说,使用UnmanagedType.BStr在In和Out参数中将DelphiWideString编组为.NetString的情况非常有效。但是在函数返回字符串的情况下它会失败。我有一个Delphi函数-functionWS(val:WideString):WideString;标准调用;开始结果:=val;结尾;程序WS1(输出结果:宽字符串);标准调用;开始结果:='ABCDE';结尾;和通讯员。网络声明–[DllImport(@"my.dll",CallingConvention=CallingConvention.StdCall,CharSet=CharSet.Unicode)][return:MarshalAs(UnmanagedType.BStr)]staticexternstringWS([MarshalAs(UnmanagedType.BStr)]string值);[DllImport("my.dll",CallingConvention=CallingConvention.StdCall,CharSet=CharSet.Unicode)]staticexternvoidWS1([MarshalAs(UnmanagedType.BStr)]outstringres);调用WS1()工作正常,而WS()抛出异常。例外情况取决于Delphi项目中包含的单元。如果包含“SysUtils”或“Classes”-.Net应用程序抛出SEHException“外部组件抛出异常”,如果两个单元都被排除,则应用程序显示“009C43B4RuntimeError203”错误对话框并终止其执行。顺便说一句,使用“ShareMem”单元不会改变任何东西。以上就是C#学习教程:VisitingDelphiDLLThrowsExceptionexception分享的全部内容。如果对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权请点击右侧联系管理员删除。如需转载请注明出处: