C#调用delphi dll接口问题
2014-12-18 22:38
302 查看
最近使用C#调用delphi dll中的PChar参数接口,结果出现了内存错误。在Stack上找到了答案,转来此处。
Delphi dll中的声明
相关知识:
register convention (see table below) so I think your only option may be to change convention in the Delphi DLL.
根据描述,我们可以知道如果我们没有在delphi dll中定义函数的导出类型,那么默认会启用register类型。而上面的C#调用代码中,我们采用的是stacall。两种接口并不兼容。所以会产生参数的传递错误。
解决方案:在delphi dll中,声明函数导出类型为stdcall。然后C#同样声明函数的接口类型为stdcall。此时dll中的函数可被正常调用。
在函数调用完成后,还需要注意的一个问题为PChar值传递问题。由于PChar类型实际为指向buffer的一个指针,所以需要在C#中预先分配充足的空间,否则会出现访问内存异常的提示。
Delphi dll中的声明
procedure PasswordDLL(month integer; password pchar); export;C#调用部分的代码
[DllImport( "DelphiPassword.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi, EntryPoint = "PasswordDLL")] public static extern void PasswordDLL( int month, [MarshalAs(UnmanagedType.LPStr)] string password );以上方法直接调用,会产生一个异常。
相关知识:
First off Since you have not stated which Delphi version your using I will answer assuming Delphi 6 for no other reason than I am familiar with it. Your Delphi procedure does not specify a calling convention in its declaration, so it won't be using stdcall as per your import. It will use the default Delphi register convention which places the first few parameters in registers rather than on the stack. If you can change your Delhpi DLL add stdcall; after the declaration and rebuild and your calling conventions will match. The table below summarizes calling conventions. |
Directive Parameter order Clean-up Passes parameters in registers? --------- --------------- -------- ------------------------------- register Left-to-right Routine Yes pascal Left-to-right Routine No cdecl Right-to-left Caller No stdcall Right-to-left Routine No safecall Right-to-left Routine NoLooking at the .NET documentation there does not seem to be a calling convention that matches Delphi's
register convention (see table below) so I think your only option may be to change convention in the Delphi DLL.
Member name Description ----------- ------------------------ Cdecl The caller cleans the stack. This enables calling functions with varargs, which makes it appropriate to use for methods that accept a variable number of parameters, such as Printf. FastCall This calling convention is not supported. StdCall The callee cleans the stack. This is the default convention for calling unmanaged functions with platform invoke. ThisCall The first parameter is the this pointer and is stored in register ECX. Other parameters are pushed on the stack. This calling convention is used to call methods on classes exported from an unmanaged DLL. Winapi Supported by the .NET Compact Framework. This member is not actually a calling convention, but instead uses the default platform calling convention. For example, on Windows the default is StdCall and on Windows CE .NET it is Cdecl.
根据描述,我们可以知道如果我们没有在delphi dll中定义函数的导出类型,那么默认会启用register类型。而上面的C#调用代码中,我们采用的是stacall。两种接口并不兼容。所以会产生参数的传递错误。
解决方案:在delphi dll中,声明函数导出类型为stdcall。然后C#同样声明函数的接口类型为stdcall。此时dll中的函数可被正常调用。
在函数调用完成后,还需要注意的一个问题为PChar值传递问题。由于PChar类型实际为指向buffer的一个指针,所以需要在C#中预先分配充足的空间,否则会出现访问内存异常的提示。
相关文章推荐
- C#调用Delphi DLL时,要注意的几个问题。
- 关于C#与Delphi DLL调用及回调问题注意事项
- delphi调用C#webservice接口的中文编码问题
- Delphi调用C#dll的问题
- C# 调用delphi生成Dll的相关问题
- c#调用delphi写的dll遇到并解决的问题
- Delphi6 调用 C# Dll 时一个编译问题
- Delphi 调用 C# Dll 时一个编译问题 mscorlib_TLB.h Ambiguity between 'String' and 'System::String'
- Delphi调用C#dll的问题
- c#调用delphi开发的dll的指针参数
- C#调用matlab dll出现的怪问题-----折腾matlab dll好久了
- 关于C#下写的Web Service 服务在Delphi下调用时的问题
- C#调用VC的DLL的接口函数参数类型转换一览表
- 求教,c#如何调用delphi编写的dll中的函数
- 关于c#下写的web service 服务在delphi下调用时的问题[转]
- C#调用VC dll提供的接口
- [整理]c#简单调用DELPHI DLL封装窗体
- PowerBuilder调用Delphi写的Dll时发生的奇怪问题。
- C#调用Delphi编写的Dll,实现绘图的功能
- 用C#调用C++DLL时的字符串指针参数传递问题