1
votes

I am using Delphi7 and I am new in it. I want to use function of Dll(Implemented in C++) in my Delphi Project. I have a function declaration in C++ like- (given by third party) Syntax

LPTSTR GetErrorString(LONG lErrorNumber)

Arguments

LONG lErrorNumber Error number

Result

LPTSTR Error string

But when I am passing a value in Delphi7 like

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.

Also tell me the proper steps to use it in my project.

2

2 Answers

4
votes

LPTSTR is just a pointer to raw character data. Delphi's equivilent is either PAnsiChar or PWideChar, depending on whether the DLL was compiled for Ansi or 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. If the DLL was compiled for Unicode, you would have to ue PWideChar instead of 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).

Also, depending on the actual calling convention being used by the DLL, the function may be using cdecl or stdcall. 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. 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.

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.

0
votes

First, a Delphi string is refcounted, and thus something else than a pointer to 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.

So the correct solution is to make the function return pansichar or pwidechar, depending on how UNICODE was defined in your C++ program.

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.