2013-06-18 2 views
1

Я пытаюсь вызвать DLL, построенную с Delphi 7 (перед поддержкой unicode), используя Delphi XE2. код выглядит так:DLL-вызов работает в Delphi 2010, но AV в Delphi XE2

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 

ответ

6

PChar maps to PAnsiChar в D7, но карты на PWideChar в D2009 и более поздних версиях. Вы на правильном пути, используя AnsiString вместо UnicodeString, но вы не можете набрать AnsiString на PWideChar. Вы должны ввести отливка его в PAnsiChar вместо этого, и вы должны изменить объявление функции DLL в D2009 +, чтобы соответствовать PAnsiChar, что DLL фактически используется:

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); 
    .. 
3

Будучи AnsiString, это ошибка для ввода-вывода V2 в PChar в любой версии Delphi с Delphi 2009. Именно тогда PChar стал псевдонимом для PWideChar вместо PAnsiChar. Если этот код работает в Delphi 2010, то это происходит совершенно случайно. Исправьте свой код, чтобы использовать правильные типы символов.

В Delphi 7, что PChar параметр PAnsiChar, поэтому изменить объявление в ваших импортных блоков Delphi 2010 и Delphi XE2, так что это в явном виде PAnsiChar. Аналогично для типа возврата.

+0

Семантически говоря, всегда было ошибкой бросать 'AnsiString' на' PChar'. Семантически корректные слепки: 'PChar (string)', 'PAnsiChar (AnsiString)', 'PWideChar (UnicodeString)', 'PWideChar (WideString)'. –

Смежные вопросы