Я использую Delphi7, и я новичок в этом.
Я хочу использовать функцию Dll (реализовано в C ++) в моем проекте Delphi.
У меня есть объявление функции в C ++, как- (дано третьей стороной)
Синтаксис
LPTSTR GetErrorString(LONG lErrorNumber)
аргументы
LONG lErrorNumber Error number
Результат
LPTSTR Error string
Но когда я передаю значение в Delphi7, как
GetErrorString(310);
Я объявляю это в моем отделении
Function GetErrorString(lErrorNumber : LongInt): String;StdCall;
implementation
Function GetErrorString;external 'Third-Party.DLL';
Я получаю пустую строку вместо фактической строки ошибок. Я не знаю точный тип данных LPTSTR.
Также скажите мне, как правильно использовать его в моем проекте.
LPTSTR
это просто указатель на необработанные символьные данные. Эквивалент Delphi является либо PAnsiChar
или же PWideChar
в зависимости от того, была ли DLL скомпилирована для Ansi или Unicode. LPTSTR
всегда является Ansi в Delphi 2007 и более ранних версиях (который включает в себя Delphi 7) и всегда Unicode в Delphi 2009 и более поздних версиях, поэтому вам, возможно, придется учитывать это. Если бы DLL была скомпилирована для Unicode, вам бы пришлось PWideChar
вместо LPTSTR
, Таким образом, лучше использовать PAnsiChar
а также PWideChar
прямо вместо LPTSTR
чтобы избежать несоответствия между различными средами (если DLL не экспортирует отдельные версии функции для обоих типов, как это делают большинство функций Win32 API).
Кроме того, в зависимости от фактического соглашения о вызовах, используемого DLL, функция может использовать cdecl
или же stdcall
, В отсутствие явного соглашения о вызовах большинство компиляторов C / C ++ используют cdecl
, но они могли бы так же легко использовать stdcall
и просто не документировать это. Так что вам нужно выяснить, потому что это делает BIG разница, потому что cdecl
а также stdcall
имеют различную семантику для управления стеком и передачи параметров.
Итак, с учетом сказанного, правильное объявление функции будет либо:
function GetErrorString(lErrorNumber: Integer): PAnsiChar; cdecl; external 'filename.dll';
Или же:
function GetErrorString(lErrorNumber: Integer): PWideChar; cdecl; external 'filename.dll';
Или же:
function GetErrorString(lErrorNumber: Integer): PAnsiChar; stdcall; external 'filename.dll';
Или же:
function GetErrorString(lErrorNumber: Integer): PWideChar; stdcall; external 'filename.dll';
Вам нужно будет провести некоторое исследование, чтобы выяснить, использует ли DLL Ansi или Unicode, и использует ли она cdecl
или же stdcall
, если в документации конкретно не указана эта информация.
Во-первых, пересчитывается строка Delphi и, следовательно, что-то еще, кроме указателя на char (LPTSTR). Я предлагаю вам избегать этих ловушек в качестве новичка, и идти на прямые указатели.
Второй LPTSTR — это указатель на однобайтовый символ (LPSTR) или указатель на двухбайтовый символ (LPWSTR) в зависимости от того, определен ли UNICODE.
Поэтому правильное решение — заставить функцию возвращать pansichar или pwidechar, в зависимости от того, как был определен UNICODE в вашей программе на C ++.
Если вы начинаете передавать символьные буферы между различными языками, убедитесь, что они используют один и тот же распределитель (для) их распределения, или убедитесь, что каждый модуль освобождает выделенные ему ресурсы.