Reputation: 2819
I'm trying to call a DLL built with Delphi 7 (before unicode support) using Delphi XE2. The code is like this:
function Foo(Param1: PChar; Var Param2: DWORD; Var Param3: DWORD): PChar; stdcall; external 'bar.dll';
Then I call:
var
V1: PChar;
V2: AnsiString;
V3, V4: DWORD;
begin
V1 := Foo(PChar(V2), V3, V4);
..
This code works in Delphi 2010 but in XE2 I get an access violation with the following stack:
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
Upvotes: 1
Views: 934
Reputation: 163277
Being an AnsiString
, it is an error to type-cast V2
to PChar
in any Delphi version since Delphi 2009. That's when PChar
became an alias for PWideChar
instead of PAnsiChar
. If that code works in Delphi 2010, then it's entirely by accident. Fix your code to use the correct character types.
In Delphi 7, that PChar
parameter is PAnsiChar
, so change the declaration in your Delphi 2010 and Delphi XE2 import units so that it's explicitly a PAnsiChar
. Likewise for the return type.
Upvotes: 3
Reputation: 595971
PChar
maps to PAnsiChar
in D7, but maps to PWideChar
in D2009 and later. You are on the right track using AnsiString
instead of UnicodeString
, but you cannot type-cast an AnsiString
to a PWideChar
. You need to type-cast it to a PAnsiChar
instead, and you need to change your DLL function declaration in D2009+ to match the PAnsiChar
that the DLL is actually using:
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);
..
Upvotes: 6