Thanks Rob, that makes sense. I'd wondered if something like that was
happening, but wasn't sure. I'd love to just use WideStrings, but I need
the DLLs to be callable from other programming languages. What I've done
now is modified the DLL to be able to return the size of those PWideChar
fields. So the calling application now does (in pseudo-code)

var
  Intf: TInterfaceDescriptor;
  IDSize, NameSize, AdditionalSize: Integer;

GetDescriptorSizes(IntfID, IDSize, NameSize, AdditionalSize);
Intf.ID := StrAllocW(IDSize);
Intf.Name := StrAllocW(NameSize);
Intf.Additional := StrAllocW(AdditionalSize);
GetDescriptor(IntfID, Intf);
//Does stuff with the descriptor (like display values in TTntEdit
controls)
StrDisposeW(Intf.ID);
StrDisposeW(Intf.Name);
StrDisposeW(Intf.Additional);

The code for GetDescriptor in the DLL is pretty much the same as before,
except now it uses StrCopyW() to copy the value into the record it has
been passed.

This all works nicely and the troublesome ID value from before is now
correctly returned to the calling application. With the slight exception
that when it trys to free the memory for the ID it raises an "invalid
pointer operation" error. All other ID values work correctly, it is just
this one that is being obstinant. For posterity's sake the troublesome
ID in question is 4 characters long and its value is "Biox". I can't
help feeling that I'm missing something really (really) simple here.

Regards,
Darren
--
Darren Ferguson
Senior Software Engineer
Clinical Software Division
Medtel Australia
Adelaide, South Australia
 
-----Original Message-----
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On
Behalf Of Rob Kennedy
Sent: Friday, 21 April 2006 5:40 AM
To: Borland's Delphi Discussion List
Subject: RE: PWideChar and DLL problem

Since IntfID is a function returning WideString, that line is actually
compiled as though it were like this:

var
  TempIntfID: WideString;

TempIntfID := AClass.IntfID;
Descriptor.ID := PWideChar(TempIntfID);

When this GetDescriptor function returns, the local variables are
released. That includes the TempIntfID variables. Therefore,
Descriptor.ID is left pointing at memory that has already been released.

The most straightforward way to solve that is to use WideStrings instead
of PWideChars. Then the compiler manages the strings' lifetimes for you.

Otherwise, you need to allocate memory for the Descriptor.ID field in
advance. You can use the JclWideStrings unit to do this:

Descriptor.ID := StrNewW(PWideChar(AClass.IntfID));

That allocates a new PWideChar buffer and fills it with the contents of
the IntfID string. Use StrDisposeW when you're finished with
Descriptor.ID.

--
Rob


_______________________________________________
Delphi mailing list -> [email protected]
http://www.elists.org/mailman/listinfo/delphi
_______________________________________________
Delphi mailing list -> [email protected]
http://www.elists.org/mailman/listinfo/delphi

Reply via email to