Erick Sasse
Erick Sasse

Reputation: 2819

DLL call works in Delphi 2010 but AV in Delphi XE2

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

Answers (2)

Rob Kennedy
Rob Kennedy

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

Remy Lebeau
Remy Lebeau

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

Related Questions