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

Returning string from DLL file

915 views
Skip to first unread message

Peter Larsson

unread,
Oct 14, 1998, 3:00:00 AM10/14/98
to
I am building a Library file with Delphi 4 and I can not get it working
to return a string from one of my functions.

This is what I have written so far,
------------------------------------------------------------------------
Function Blabla(What: Double): AnsiString; StdCall;

Var sReturn: AnsiString

Begin
If What < 0 Then
sReturn := 'Negative'
Else
If What > 0 Then
sReturn := 'Positive'
Else
sReturn := 'Zero';

Blabla := sReturn;
End;
------------------------------------------------------------------------
But when referencing this function from Visual Basic, VB bombs...
Please help.

//Peter Larsson

Thaddy de Koning

unread,
Oct 14, 1998, 3:00:00 AM10/14/98
to
You shouldn't use delphi strings with VB or C++, but rather Pchars or
Pwidechars.
Even with Delphi applications, if you would use delphi strings from delphi
dll's you need the delphimm.dll to ship with your application.

So, rewrite your code to accept Pchars or in the case of ansistrings
Pwidechars.

Peter Larsson wrote in message <3624B234...@workshop.ms>...

Philippe Ranger

unread,
Oct 14, 1998, 3:00:00 AM10/14/98
to
Peter: >>But when referencing this function from Visual Basic, VB bombs...
<<

When your function returns "an AnsiString", actually it's returning an
address, which the VB caller takes to be a pchar or a reference to a
bstring. The actual string is allocated through the dll's string manager, on
its heap. This is always a good way to trouble. In the case in point, the
Delphi string manager has no indication that the return string is still in
use after the function ends, so its reference count goes down to 0, and it
scraps the memory.

It would be better for the caller to allocate its own memory, as a
fixed-length string, and pass the Dll function both this, and the length of
it in a second argument. In VB —

Declare function blabla lib ... (byVal what as double, byVal retStr as
string, byVal retSize as long) as long

In Delphi —

Function blabla(what: double; pReturn: pChar; retSize: integer): integer;

As you can see, passing the VB string by val passes the address of its first
char. I've left blabla a function so it can return an error code if needed.

In all this, I'm just following the WinAPI itself (check the WinAPI help).
The rules are always the same. One, the last code that deals with a string
must also be the one that creates it and sizes it. Two, as this will
normally be the caller, it must pass both the string address and the buffer
size allocated. Three, of course a function can't return a string. (It's not
totally impossible to achieve this, it's just so complicated that the WinAPI
doesn't do it, afaik, and only some jury-rigged third-party libs use it.)

Add four: AnsiStrings are private to Delphi, so they're not for Dll's that
will be used elsewhere.

PhR

Ken White

unread,
Oct 14, 1998, 3:00:00 AM10/14/98
to
Peter,

You can't use Strings between VB and Delphi; you'll need to have
the VB app pass in a PChar and the length, and modify that in
your DLL.

Ken
--
Ken White
kwh...@westelcom.com

Clipper Functions for Delphi
http://members.aol.com/clipfunc/

Peter Larsson wrote:
>
> I am building a Library file with Delphi 4 and I can not get it working
> to return a string from one of my functions.
>
> This is what I have written so far,
> ------------------------------------------------------------------------
> Function Blabla(What: Double): AnsiString; StdCall;
>
> Var sReturn: AnsiString
>
> Begin
> If What < 0 Then
> sReturn := 'Negative'
> Else
> If What > 0 Then
> sReturn := 'Positive'
> Else
> sReturn := 'Zero';
>
> Blabla := sReturn;
> End;
> ------------------------------------------------------------------------

> But when referencing this function from Visual Basic, VB bombs...

> Please help.
>
> //Peter Larsson

The African Chief

unread,
Oct 14, 1998, 3:00:00 AM10/14/98
to
In article <3624B234...@workshop.ms>
Peter Larsson <pe...@workshop.ms> wrote:

> I am building a Library file with Delphi 4 and I can not get it working
> to return a string from one of my functions.
>
> This is what I have written so far,
> ------------------------------------------------------------------------
> Function Blabla(What: Double): AnsiString; StdCall;
>
> Var sReturn: AnsiString
>
> Begin
> If What < 0 Then
> sReturn := 'Negative'
> Else
> If What > 0 Then
> sReturn := 'Positive'
> Else
> sReturn := 'Zero';
>
> Blabla := sReturn;
> End;
> ------------------------------------------------------------------------
> But when referencing this function from Visual Basic, VB bombs...
> Please help.

You cannot export AnsiStrings from a Delphi DLL for use
with other compilers, because AnsiStrings involve all sorts
of memory management by Delphi (which is different from
those in VB or C++). You need to return a pChar (preferably
as a parameter) - e.g.,

Function Blabla(What: Double; ReturnValue:pChar): longint; StdCall;
Begin
... // do stuff
.. // do stuff
Strcopy(ReturnValue, pChar(sReturn));.
Result := Strlen(ReturnValue);
end;

Best regards, The Chief
--------
Dr. Abimbola A. Olowofoyeku (The African Chief)
Email: la...@keele.ac.uk
Homepage: http://ourworld.compuserve.com/homepages/African_Chief/
Author of: Chief's Installer Pro 4.60 for Win16 and Win32
ftp://ftp.demon.co.uk/pub/ibmpc/win3/apps/chief/pro/chief460.zip


Peter Larsson

unread,
Oct 15, 1998, 3:00:00 AM10/15/98
to
I found something on the web last night, the BStr string type.
BStr is the native format for VB, and the example worked just fine
if it wasnt for one thing; The function returned an unicode string...
------------------------------------------------------------------------
Library vb4dll32;

Uses Ole2,Sysutils;

Function StringTest(): TBStr; StdCall;

Var sItem: WideString;

Begin
sItem := 'Peter Larsson';
StringTest := SysAllocStringLen(PWideChar(sItem), Length(sItem));
End;

Exports StringTest Index 1;

Begin
End.
------------------------------------------------------------------------
How to eliminate this unicode output? I found this source at
http://www.thecave.com/tips/delphi/vb4dll.html

//Peter Larsson

Philippe Ranger

unread,
Oct 15, 1998, 3:00:00 AM10/15/98
to
Peter: >>

Function StringTest(): TBStr; StdCall;
Var sItem: WideString;
Begin
sItem := 'Peter Larsson';
StringTest := SysAllocStringLen(PWideChar(sItem), Length(sItem));
End;
<<

I didn't even know of SysAllocStringLen() until you posted this! Remember to
call SysFreeString() in the caller code.

Me, I'm still chary of allocating memory in one piece of code, written one
day in one place, and deallocating it in another one, written somewhere else
in another language by someone else.

SysAllocStringByteLen() should return an Ansi-code string. Try it.

PhR

0 new messages