我在delphi中有一个程序:
procedure PasswordDLL(month integer; password pchar);
export;
程序应该输入我传入的“密码”pchar的密码。 从我的谷歌和阅读.... 参考:HERE和HERE
我想出来了:
[DllImport(
"DelphiPassword.dll",
CallingConvention = CallingConvention.StdCall,
CharSet = CharSet.Ansi,
EntryPoint = "PasswordDLL")]
public static extern void PasswordDLL(
int month,
[MarshalAs(UnmanagedType.LPStr)] string password
);
然后我打电话:
string pass = "";
PasswordDLL(2, pass);
所以输出到“pass”字符串的密码。
但我会得到BadImageFormatException未处理:尝试加载格式不正确的程序。 (HRESULT异常:0x8007000B)
听起来我用的功能格式错了? 我想知道我是否为PChar使用了不正确的UnmanagedType,但从阅读开始,它是LPWStr和LPStr ..我错过了什么吗?
提前致谢...
答案 0 :(得分:2)
首先关闭因为您没有说明使用哪个Delphi版本我会回答假设 Delphi 6 除了我熟悉之外没有其他原因。
您的Delphi过程未在其声明中指定调用约定,因此根据您的导入,它不会使用 stdcall 。它将使用默认的Delphi 寄存器约定,它将前几个参数放在寄存器中而不是堆栈中。如果您可以在声明和重建之后更改Delhpi DLL,请添加 stdcall; ,并且您的调用约定将匹配。
下表总结了调用约定。
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 No
查看.NET文档似乎没有符合Delphi的注册约定的调用约定(参见下面的表)所以我认为你唯一的选择可能是更改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(6)Pchar(指向空终止的ANSI字符串的指针)编组看起来是正确的。