2013-11-12 4 views
1

Я использую Delphi7, и я новичок в нем. Я хочу использовать функцию Dll (реализованную на C++) в моем проекте Delphi. У меня есть объявление функции в C++ как- (данное третьей стороной) Синтаксисвызов функции dll в C++ в delphi7

LPTSTR GetErrorString(LONG lErrorNumber) 

Аргументы

LONG lErrorNumber Error number 

Результат

LPTSTR Error string 

Но когда я передаю значение в Delphi7 подобные

GetErrorString(310); 

я заявляю это в моем Unit-

Function GetErrorString(lErrorNumber : LongInt): String;StdCall; 

implementation 

Function GetErrorString;external 'Third-Party.DLL'; 

Я получаю пустую строку вместо фактической строки ошибки. Я не знаю точный тип данных LPTSTR.

Также скажите мне, какие меры необходимо использовать в моем проекте.

ответ

4

LPTSTR - это просто указатель на сырые данные символа. Эквивалент Delphi равен PAnsiChar или PWideChar, в зависимости от того, была ли DLL скомпилирована для Ansi или Unicode. LPTSTR всегда Ansi в Delphi 2007 и ранее (включая Delphi 7) и всегда Unicode в Delphi 2009 и более поздних версиях, поэтому вам, возможно, придется это учитывать. Если DLL была скомпилирована для Unicode, вам нужно будет ue 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, если в документации не указано конкретно эта информация.

0

Во-первых, строка Delphi refcounted и, следовательно, нечто иное, чем указатель на char (LPTSTR). Я предлагаю вам избегать этих ловушек в качестве новичка и идти за прямыми указателями.

Второй LPTSTR является указателем на один байтовый символ (LPSTR) или указателем на двухбайтовый символ (LPWSTR) в зависимости от того, установлен ли UNICODE.

Таким образом, правильное решение заключается в том, чтобы вернуть функцию pansichar или pwidechar в зависимости от того, как UNICODE был определен в вашей программе на C++.

Если вы начинаете передавать символьные буферы между разными языками, убедитесь, что они используют один и тот же распределитель для (де) их выделения или убедитесь, что каждый модуль освобождает выделение, которое он делает.