PChar в библиотеке D2010, вызываемой в приложении D5, кажется поврежденным - PullRequest
0 голосов
/ 05 апреля 2011

Я видел много ответов о вызове старой библиотеки DLL в D2010 (Unicode), но проблема в том, что я делаю все наоборот. Мы пишем новые части приложения (DLL) в D2010. Родительское приложение написано на D5 и не может быть временно заменено на приложение D2010 (возможно, пару лет).

Параметры и переменные DLL могут быть изменены (D2010), но к родительскому приложению (D5) нельзя прикоснуться. Целочисленные параметры, кажется, в порядке, это параметры строки / PChar, которые не работают. Например, строка пути к файлу «D: \ home \ special \ files \» выглядит как «??????????????????» когда я это оцениваю. Я изменил параметры DLL на PAnsiChar, но это не помогло.

Если DLL-библиотека и хост-приложение скомпилированы в одной и той же версии Delphi, это работает нормально (до того, как я добавил Ansi).

Есть идеи?


Пример кода:

В хосте (D5):

fpLoadImage: procedure(sFilename: PChar); stdcall;
.
.
.
    @fpLoadImage    := GetProcAddress(hLib, 'LoadImage');

В DLL (D2010):

procedure LoadImage(sFileName: pAnsiChar);
var
  TempStr: string;
begin
  TempStr := sFileName;
  frmViewer.ImageFileName := TempStr;
  frmViewer.PCurrentImageId(-2);
end;

Ответы [ 5 ]

3 голосов
/ 05 апреля 2011

Это потому, что тип данных "string" в вашем случае unicode и вы теперь получаете PAnsiChar. Попробуйте объявить вашу строковую переменную "TempStr" как AnsiString.

2 голосов
/ 05 апреля 2011

Ваша DLL должна объявить TempStr как AnsiString, а не string.Вы делаете неявное преобразование из AnsiString в UnicodeString, когда вы присваиваете ему sFileName.Включение подсказок и предупреждений советовало бы вам об этом ...:)

0 голосов
/ 05 апреля 2011

Спасибо Тандрей.Я забыл поставить StdCall;в конце, и это испортило параметры PChar.Это всегда простые вещи, которые получают человек.

Причина, по которой в процедуре была строка вместо ansistring, заключается в том, что я менял процедуру во время устранения неполадок и забыл вернуть ее, прежде чем вырезать и вставить код. Извините за это.

Спасибо всем за помощь.Мне просто нужно написать код, чтобы он теперь работал в ANSI и Unicode.Я думаю, что я нашел вызов где-то, чтобы оценить систему до преобразования

Том

0 голосов
/ 05 апреля 2011

Я не вижу ничего плохого в коде, который вы опубликовали.

Конечно, как многие уже упоминали, вы делаете неявное преобразование из pAnsiChar в AnsiString в строку в строке

TempStr := sFileName;

Но это не повредит строку.

Вы пытались использовать ShowMessage(TempStr) сразу после назначения?(Просто чтобы убедиться, что это не отладчик delphi, который не оценивает строку должным образом в отладке).Или даже поставьте точку останова в начале функции и оцените (в отладке) как Pchar(sFileName), так и PAnsiChar(sFileName) (чтобы увидеть, есть ли у указателя допустимые данные для начала)

Еще одна вещь, которую япроверил бы, какая именно версия DLL была загружена во время отладки.Возможно, DLL, которая была загружена во время отладки, была не последней с вашим изменением «ansi».Я не думаю, что Delphi гарантирует, что DLL, которая будет загружена хост-приложением, будет той, что была только что скомпилирована, это будет первая, которую хост-приложение найдет в пути поиска DLL Windows (я могу ошибаться в этомхоть).

Ох ... и последнее, но не менее важное, убедитесь, что вы случайно не удалили "stdcall" в DLL ... хммм ... На самом деле, вы должны сделать это в первую очередь!: P

Это все, что я могу думать прямо сейчас ...

0 голосов
/ 05 апреля 2011

Как все говорили, вы заставляете PAnsichar к строке typecast, когда делаете:

TempStr := sFileName;

, потому что TempStr - string.Это должно быть AnsiString.

Если вы действительно хотите работать с strings вместо ansistrings, вы должны сделать:

TempStr := string(AnsiString(sFileName)); Это может работать дляВы (не проверено).

Просто чтобы прояснить:

В Delphi 2010:

  • Pchar должно быть приведено к string (Unicode)
  • PAnsiChar должно быть приведено к AnsiString (ansi).

Проверьте эту ссылку для серии советов о преобразовании Unicode:

Delphi в мире Unicode, часть III: Unicodification Your Code

Вы также можете проверить класс TEncoding: TEncoding

...