Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

VC++ DLL and Delphi PChars

49 views
Skip to first unread message

Dick Rowe

unread,
Jan 24, 1999, 3:00:00 AM1/24/99
to
I have created a DLL with Visual C++ v6 that I want to use with Delphi v4
and at work with PowerBuilder v6. everything works fine from PowerBuilder,
but I am having the following 'difficulties' getting some of it to work with
Delphi.

The Delphi "interface section" includes these imported functions from the
dll ...

function Count_Chars( Source : Pchar; LookFor : Pchar ) : integer; cdecl;
function Get_Token( Source : Pchar; Separator : Pchar ) : Pchar; cdecl;
function Get_String_Map( Map : Pchar; Data : Pchar; Key : Pchar; Token :
Pchar ) : Pchar; cdecl;
function Get_Next_Map( Data : Pchar; Key : Pchar; Token : Pchar ) : Pchar;
cdecl;
function IsArchiveBitSet( FileName : PChar ) : boolean; cdecl;
function ClearArchiveBit( FileName : PChar ) : integer; cdecl;

The functions above which return boolean or integer values to Delphi from
the dll work fine in both the Delphi IDE and from the created Delphi EXE.
The problem I am having is that the functions expecting a PChar (char *)
from the dll work fine when I run the Delphi program from the Delphi IDE,
but crash with a memory write violation when executing the Delphi EXE file
from disk.

What am I missing? I assume that I have to set a compiler or linker switch
in Delphi, but don't know what it might be.

Alex

unread,
Jan 24, 1999, 3:00:00 AM1/24/99
to
On Sun, 24 Jan 1999 09:26:17 -0600, "Dick Rowe" <dr...@dwave.net>
I had the same problem. The only workaround I found was to get rid of
the PChar's and use pointer to array of chars, smth. like that:

szFileName : array[0..MAX_PATH] of char;

and use @szFileName. You can try the same approach.
Alex
ErgoLight Usability Software
Visit us at www.ergolight-sw.com

Peter Below (TeamB)

unread,
Jan 25, 1999, 3:00:00 AM1/25/99
to

It has nothing to do with any switches, it has to do with the fact that a
PChar is a pointer type. Declaring a variable

Var
Buf: PChar;

Gives you 4 bytes of storage to hold a pointer, it does not allocate memory
for the character buffer itself. And you need to do that if you want to pass
Buf to a DLL function that is supposed to copy characters into the buffer. And
you better be able to tell the DLL how large the buffer is, or else you need a
way to figure out how large the buffer needs to be to fit the data.

Use StrAlloc to allocate memory for PChar variables, or declare the variables
as array [0..x] of char instead. This really gives you x+1 bytes of storage
and Delphi will automatically pass the address of the buffer when you try to
pass such a variable to a Pchar parameter.

Oh, you should not use Boolean as a return type in functions that are to be
used in non-delphi environments. Use LongBool instead, or BOOL.

> function Get_Token( Source : Pchar; Separator : Pchar ) : Pchar; cdecl;
> function Get_String_Map( Map : Pchar; Data : Pchar; Key : Pchar; Token :
> Pchar ) : Pchar; cdecl;
> function Get_Next_Map( Data : Pchar; Key : Pchar; Token : Pchar ) : Pchar;
> cdecl;

I always shudder when I see functions that return a PChar. This is generally a
receipe for desaster. You will note
that the API contains no functions of this type, for a good reason (who
owns the returned pointer and has to free it?). If a DLL routine needs
to return data as a zero-terminated string it has to receive a
preallocated buffer (specifically: a pointer to such a buffer) from the
caller, hopefully together with information on the buffers size. A
Delphi routine would use StrLCOpy or StrPLCopy to copy data into such a
buffer. If the data can vary widely in size there should be a way for
the application to ask the DLL what size the buffer needs to be (can be
a separate function, can be handled by returning the required size if
the buffer is too small).

Peter Below (TeamB) 10011...@compuserve.com)
No replies in private e-mail, please, unless explicitely requested!


0 new messages