1

我正在使用 Delphi7,我是新手。我想在我的 Delphi 项目中使用 Dll(在 C++ 中实现)的功能。我在 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 的确切数据类型。

还告诉我在我的项目中使用它的正确步骤。

4

2 回答 2

4

LPTSTR只是一个指向原始字符数据的指针。Delphi 的等价物是PAnsiCharPWideChar,这取决于 DLL 是为 Ansi 还是 Unicode 编译的。 LPTSTR在 Delphi 2007 及更早版本(包括 Delphi 7)中始终为 Ansi,在 Delphi 2009 及更高版本中始终为 Unicode,因此您可能需要考虑这一点。如果 DLL 是为 Unicode 编译的,则必须使用 uePWideChar而不是LPTSTR. 因此,最好直接使用PAnsiCharPWideChar而不是LPTSTR避免不同环境之间的不匹配(除非 DLL 为这两种类型导出单独的函数版本,就像大多数 Win32 API 函数一样)。

此外,根据 DLL 使用的实际调用约定,该函数可能使用cdeclstdcall. 在没有显式调用约定的情况下,大多数 C/C++ 编译器使用cdecl,但它们可以很容易地使用stdcall,只是不记录它。所以你需要找出答案,因为它有很大的不同,因为堆栈管理和参数传递的语义不同cdeclstdcall

因此,话虽如此,正确的函数声明将是:

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

于 2013-11-12T17:57:42.883 回答
0

首先,一个 Delphi 字符串被引用,因此不是指向 char (LPTSTR) 的指针。我建议您作为初学者避免这些陷阱,并寻求直接的指针。

第二个 LPTSTR 是指向单字节字符 (LPSTR) 的指针,或指向双字节字符 (LPWSTR) 的指针,具体取决于是否定义了 UNICODE。

所以正确的解决方案是让函数返回 pansichar 或 pwidechar,这取决于 UNICODE 在 C++ 程序中是如何定义的。

如果您开始在不同语言之间传递字符缓冲区,请确保它们使用相同的分配器来(取消)分配它们,或者确保每个模块释放它所做的分配。

于 2013-11-12T11:25:05.993 回答