Re: Testing Delphi DLL crashes VB6 IDE
- From: Rob Kennedy <me3@xxxxxxxxxxx>
- Date: Wed, 15 Oct 2008 01:28:42 -0500
Bruce M. Axtens wrote:
library BOSLAD;
uses
BOSLADCode in 'BOSLADCode.pas';
exports
version,
DMesg,
foo;
{$R *.res}
begin
end.
---
interface
function version() : Double; stdcall;
procedure DMesg(sText : PWideChar; sHead : PWideChar ); stdcall;
function foo() : PWideChar; stdcall;
implementation
uses Windows;
var s : WideString;
function version() : Double;
begin
result := 0.001;
end;
procedure DMesg( sText : PWideChar; sHead : PWideChar);
begin
Windows.MessageBoxW(0, sText, sHead, 0);
end;
function foo() : PWideChar;
begin
s := 'My dog''s got fleas';
result := PWideChar(s);
end;
Although the type in foo is now accurate, there's still the problem that s goes out of scope before the function returns, and thus the pointer is not valid by the time it arrives at the caller.
But since the address that s held is probably still within your process's address space, and COM probably hasn't re-allocated it to anything else, it probably still contains the same characters it did a moment ago when it was still a valid pointer, so the caller will blithely read it and get what you were expecting, so it appears to work. But a program that accidentally works most of the time is still broken.
end.
---
// This is the type library for BOSLAD.dll
[
uuid(0C55D7DA-0840-40c0-B77C-DC72BE9D109E),
helpstring("BOSLAD TypeLib"),
lcid(0x0409),
version(1.0)
]
library BOSLAD
{
[
helpstring("Functions in BOSLAD.DLL"),
version(1.0),
dllname("BOSLAD.dll")
]
module BOSLADFunctions
{
[helpstring("version"), entry("version")]
void __stdcall version( [out,retval] double* res );
[helpstring("DMesg"), entry("DMesg")]
void __stdcall DMesg( [in] BSTR msg, [in] BSTR head );
[helpstring("foo"), entry("foo")]
void __stdcall foo( [out,retval] BSTR* msg );
A BSTR is not just a pointer to a wide character. A BSTR (a "binary string") is a special type that is null-terminated, has a length indicator, and has its memory managed by special COM API functions.
Delphi's declaration of the BSTR type is wrong, as I recall. It claims it's just a PWideChar. That's particularly strange since Delphi actually wraps all the special BSTR semantics into a built-in type, WideString. I think if you change all your PWideChar types above to WideString, everything will work just right. Change your DMesg implementation back to what it was before.
WideStrings are not reference-counted like AnsiStrings are. That means that every WideString assignment statement makes a new copy of the string. Thus, your foo implementation would be non-optimal, as written:
var
s: WideString;
begin
s := 'bar'; // Creates a new WideString value
Result := s; // Makes a new copy; there are two now.
end; // s goes out of scope. Now back to one copy of "bar"
Avoid superfluous WideStrings. The compiler won't optimize them away because the optimizer runs _after_ the built-in WideString code has been expanded to call the API functions, and the optimizer never removes external function calls (since it doesn't know what desirable side effects they might have).
begin
Result := 'bar'; // Creates a new WideString value
end; // Compiler knows not to destroy Result's contents.
I don't know how VB deals with Unicode and non-Unicode strings, but I assume that if you're giving it the type library above, VB will work out whatever it needs to do to call the functions properly and receive their return values.
}
};
---
Sub Main()
Dim cfg As New CFGProject.cfg
cfg.Load "test.cfg"
Dim s As String
s = cfg.Recall("msg")
DMesg s, "" & version
s = foo
DMesg s, "" & version
End Sub
---
#test.cfg
msg=毅訜訝
--
Rob
.
- Follow-Ups:
- Re: Testing Delphi DLL crashes VB6 IDE
- From: Bruce M. Axtens
- Re: Testing Delphi DLL crashes VB6 IDE
- References:
- Testing Delphi DLL crashes VB6 IDE
- From: Bruce M. Axtens
- Re: Testing Delphi DLL crashes VB6 IDE
- From: Rob Kennedy
- Re: Testing Delphi DLL crashes VB6 IDE
- From: Bruce M. Axtens
- Testing Delphi DLL crashes VB6 IDE
- Prev by Date: Re: Testing Delphi DLL crashes VB6 IDE
- Next by Date: Re: Testing Delphi DLL crashes VB6 IDE
- Previous by thread: Re: Testing Delphi DLL crashes VB6 IDE
- Next by thread: Re: Testing Delphi DLL crashes VB6 IDE
- Index(es):