简体   繁体   English

在delphi7中调用C ++ dll函数

[英]C++ dll function calling in delphi7

I am using Delphi7 and I am new in it. 我正在使用Delphi7,我是新手。 I want to use function of Dll(Implemented in C++) in my Delphi Project. 我想在我的Delphi项目中使用Dll的功能(在C ++中实现)。 I have a function declaration in C++ like- (given by third party) Syntax 我在C ++中有一个函数声明 - (由第三方给出)语法

LPTSTR GetErrorString(LONG lErrorNumber)

Arguments 参数

LONG lErrorNumber Error number

Result 结果

LPTSTR Error string

But when I am passing a value in Delphi7 like 但是当我在Delphi7中传递一个值时就像

GetErrorString(310);

I am declaring it in my unit- 我在我的单位宣布它 -

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

implementation   

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

I am receiving blank string instead of actual Error String. 我收到空字符串而不是实际的错误字符串。 I don't know the exact data type of LPTSTR. 我不知道LPTSTR的确切数据类型。

Also tell me the proper steps to use it in my project. 还告诉我在我的项目中使用它的正确步骤。

LPTSTR is just a pointer to raw character data. LPTSTR只是指向原始字符数据的指针。 Delphi's equivilent is either PAnsiChar or PWideChar , depending on whether the DLL was compiled for Ansi or Unicode. Delphi的等值是PAnsiCharPWideChar ,取决于DLL是为Ansi还是Unicode编译的。 LPTSTR is always Ansi in Delphi 2007 and earlier (which includes Delphi 7) and always Unicode in Delphi 2009 and later, so you may need to account for that. LPTSTR在Delphi 2007及更早版本(包括Delphi 7)中始终是Ansi,在Delphi 2009及更高版本中始终是Unicode,因此您可能需要考虑到这一点。 If the DLL was compiled for Unicode, you would have to ue PWideChar instead of LPTSTR . 如果DLL是为Unicode编译的,那么你必须使用PWideChar而不是LPTSTR As such, it is better to use PAnsiChar and PWideChar directly instead of LPTSTR to avoid mismatches between different environments (unless the DLL exports separate versions of the function for both types, like most Win32 API functions do). 因此,最好直接使用PAnsiCharPWideChar而不是LPTSTR来避免不同环境之间的不匹配(除非DLL为两种类型导出函数的单独版本,就像大多数Win32 API函数那样)。

Also, depending on the actual calling convention being used by the DLL, the function may be using cdecl or stdcall . 此外,根据DLL使用的实际调用约定,该函数可能使用cdeclstdcall In the absence of an explicit calling convention, most C/C++ compilers use cdecl , but they could just as easily be using stdcall and just not document it. 在没有显式调用约定的情况下,大多数C / C ++编译器都使用cdecl ,但它们可以很容易地使用stdcall而不是记录它。 So you need to find out, because it makes a BIG difference because cdecl and stdcall have different semantics for stack management and parameter passing. 所以,你需要找出来,因为它使一个很大的区别,因为cdeclstdcall对堆栈的管理和参数传递不同的语义。

So, with that said, the correct function declaration will be either: 所以,说到这一点,正确的函数声明将是:

function GetErrorString(lErrorNumber: Integer): PAnsiChar; cdecl; external 'filename.dll';

Or: 要么:

function GetErrorString(lErrorNumber: Integer): PWideChar; cdecl; external 'filename.dll';

Or: 要么:

function GetErrorString(lErrorNumber: Integer): PAnsiChar; stdcall; external 'filename.dll';

Or: 要么:

function GetErrorString(lErrorNumber: Integer): PWideChar; stdcall; external 'filename.dll';

You will have to do some research to find out whether the DLL is using Ansi or Unicode, and whether it is using cdecl or stdcall , if the documentation does not specifically state that information. 您将不得不进行一些研究,以确定DLL是使用Ansi还是Unicode,以及它是否使用cdeclstdcall ,如果文档没有明确说明该信息。

First, a Delphi string is refcounted, and thus something else than a pointer to char (LPTSTR). 首先,重新计算Delphi字符串,因此不是指向char(LPTSTR)的指针。 I suggest you avoid those traps as beginner, and go for straight pointers. 我建议你避免那些陷阱作为初学者,并直接指针。

Second LPTSTR is a pointer to a one byte char (LPSTR), or a pointer to a two byte char (LPWSTR) depending on if UNICODE is defined. 第二个LPTSTR是指向一个字节字符(LPSTR)的指针,或指向两个字节字符(LPWSTR)的指针,具体取决于是否定义了UNICODE。

So the correct solution is to make the function return pansichar or pwidechar, depending on how UNICODE was defined in your C++ program. 因此,正确的解决方案是使函数返回pansichar或pwidechar,具体取决于在C ++程序中如何定义UNICODE。

If you start passing character buffers between different languages, make sure they use the same allocator to (de)allocate them, or make sure that each module frees the allocations that it makes. 如果您开始在不同语言之间传递字符缓冲区,请确保它们使用相同的分配器来(de)分配它们,或确保每个模块释放它所做的分配。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM