我正在尝试使用Delphi XE2调用使用Delphi 7构建的DLL(在unicode支持之前)。 代码是这样的:
function Foo(Param1: PChar; Var Param2: DWORD; Var Param3: DWORD): PChar; stdcall; external 'bar.dll';
然后我打电话给:
var
V1: PChar;
V2: AnsiString;
V3, V4: DWORD;
begin
V1 := Foo(PChar(V2), V3, V4);
..
此代码适用于Delphi 2010,但在XE2中,我使用以下堆栈获取访问冲突:
System.UTF8ToUnicodeString(nil)
System.UTF8ToString(nil)
System.TObject.ClassName
Vcl.Forms.IsClass(???,Exception)
Vcl.Forms.TApplication.HandleException($2083120)
Vcl.Controls.TWinControl.MainWndProc(???)
System.Classes.StdWndProc(726196,273,6106,2365402)
:776e77d8 ; C:\Windows\SysWOW64\user32.dll
:776e78cb ; C:\Windows\SysWOW64\user32.dll
:776ef139 ; C:\Windows\SysWOW64\user32.dll
:776eaaa6 user32.SendMessageW + 0x52
:749fb322 ; C:\Windows\WinSxS\x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.9200.16579_none_8937eec6860750f5\comctl32.dll
:749fb27e ; C:\Windows\WinSxS\x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.9200.16579_none_8937eec6860750f5\comctl32.dll
:776e77d8 ; C:\Windows\SysWOW64\user32.dll
:776e78cb ; C:\Windows\SysWOW64\user32.dll
:776ebd11 user32.ChangeWindowMessageFilterEx + 0x71
:776ebd39 user32.CallWindowProcW + 0x1c
Vcl.Controls.TWinControl.DefaultHandler(???)
:0048b0c1 TWinControl.DefaultHandler + $DD
:0048afc4 TWinControl.WndProc + $5B8
:0049d031 TButtonControl.WndProc + $71
:004535f2 StdWndProc + $16
:776e77d8 ; C:\Windows\SysWOW64\user32.dll
:776e78cb ; C:\Windows\SysWOW64\user32.dll
:776e899d ; C:\Windows\SysWOW64\user32.dll
:776e8a66 user32.DispatchMessageW + 0x10
答案 0 :(得分:6)
PChar
在D7中映射到PAnsiChar
,但在D2009及更高版本中映射到PWideChar
。您使用AnsiString
而不是UnicodeString
走在正确的轨道上,但是您无法将AnsiString
输入到PWideChar
。您需要将其类型转换为PAnsiChar
,并且需要在D2009 +中更改DLL函数声明以匹配DLL实际使用的PAnsiChar
:
function Foo(Param1: PAnsiChar; var Param2: DWORD; var Param3: DWORD): PAnsiChar; stdcall; external 'bar.dll';
var
V1: PAnsiChar;
V2: AnsiString;
V3, V4: DWORD;
begin
V1 := Foo(PAnsiChar(V2), V3, V4);
..
答案 1 :(得分:3)
作为AnsiString
,自Delphi 2009以来在任何Delphi版本中向V2
输入PChar
是错误的。当PChar
成为PWideChar
时PAnsiChar
的别名,而不是PChar
。如果该代码在Delphi 2010中有效,那么它完全是偶然的。修复代码以使用正确的字符类型。
在Delphi 7中,PAnsiChar
参数为PAnsiChar
,因此更改Delphi 2010和Delphi XE2导入单元中的声明,使其明确为{{1}}。同样适用于返回类型。