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
So, rewrite your code to accept Pchars or in the case of ansistrings
Pwidechars.
Peter Larsson wrote in message <3624B234...@workshop.ms>...
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
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
> 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
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
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