Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: DLL exception problems between D2010 and Xe4


This question is answered. Helpful answers available: 2. Correct answers available: 1.


Permlink Replies: 4 - Last Post: Mar 26, 2015 7:33 AM Last Post By: Peter Lee
Peter Lee

Posts: 3
Registered: 10/18/02
DLL exception problems between D2010 and Xe4  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 20, 2015 7:40 AM
I am writing code to go into a DLL using D2010, it uses an expensive library (£1000) (that does not come with source) and is only Delphi 2010 or earlier compatible.

The routine that it giving me problems has only one component in it (everything else is rem'd out) which is a TMemoryStream. The TMemoryStream is supplied as a argument to the routine. I can get the length of the stream without a problem but when I do a Stream.seek(0, soFromBeginning) I get an exception.

I am using test code which will compile happily under D2010 or Xe4. When compiled and run under D2010 it works fine, no exceptions. When compiled and run under Xe4 I get memory exception error as soon as the seek is executed. I have excluded anything to do with wide strings but have, at the moment, run out of ideas.

Any clues would be gratefully received.
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: DLL exception problems between D2010 and Xe4  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 20, 2015 9:35 AM   in response to: Peter Lee in response to: Peter Lee
Peter wrote:

The routine that it giving me problems has only one component
in it (everything else is rem'd out) which is a TMemoryStream.
The TMemoryStream is supplied as a argument to the routine.
I can get the length of the stream without a problem but when
I do a Stream.seek(0, soFromBeginning) I get an exception.

You cannot safely pass an object across the DLL boundary unless both EXE
and DLL are compiled with the same version of Delphi and with Runtime Packages
enabled so they share a common RTL. So if you are trying to pass a TMemoryStream
from your EXE to the DLL to the library, you will have to change the design
of your DLL. It can use a TMemoryStream internally when interacting with
the library, but you will have to pass your desired data across the DLL boundary
in another safer manner, such as with raw pointers to memory buffers. Hard
to say for sure since you did not show the actual code you are having trouble
with.

--
Remy Lebeau (TeamB)
Peter Lee

Posts: 3
Registered: 10/18/02
Re: DLL exception problems between D2010 and Xe4  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 20, 2015 1:04 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Remy Lebeau (TeamB) wrote:
Peter wrote:

The routine that it giving me problems has only one component
in it (everything else is rem'd out) which is a TMemoryStream.
The TMemoryStream is supplied as a argument to the routine.
I can get the length of the stream without a problem but when
I do a Stream.seek(0, soFromBeginning) I get an exception.

You cannot safely pass an object across the DLL boundary unless both EXE
and DLL are compiled with the same version of Delphi and with Runtime Packages
enabled so they share a common RTL. So if you are trying to pass a TMemoryStream
from your EXE to the DLL to the library, you will have to change the design
of your DLL. It can use a TMemoryStream internally when interacting with
the library, but you will have to pass your desired data across the DLL boundary
in another safer manner, such as with raw pointers to memory buffers. Hard
to say for sure since you did not show the actual code you are having trouble
with.

--
Remy Lebeau (TeamB)

Hi Remy

Thanks for the information; its something that I wasn't aware of however now you point it out its easy to see why (I should have thought harder about it). Re-coding to put everything inside the DLL shouldn't be a problem, I should be able to pass an integer and two AnsiStrings to the DLL find the record and then collect the blob from the table all whilst still inside the DLL.

Once I had rem'd out the code in the routine there was only 1 line of code left which was the memorystream.seek(), so your answer must be the reason.

Thanks for the help.

Peter
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: DLL exception problems between D2010 and Xe4  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 20, 2015 1:50 PM   in response to: Peter Lee in response to: Peter Lee
Peter wrote:

I should be able to pass ... two AnsiStrings to the DLL

Passing an (Ansi/Unicode)String across the DLL boundary is not safe either,
for the same reasons that passing an object is not safe. If the EXE and
DLL are not compiled using the same Delphi version, and are not sharing a
single instance of the RTL, then the (Ansi/Unicode)String's memory will not
be managed correctly, and its internal memory layout may even be incompatible
between the two modules. So will have to pass the (Ansi/Unicode)String data
usin P(Ansi/Wide)Char instead. Or use WideString, which is safe (because
its memory is managed by Windows, not the Delphi RTL).

--
Remy Lebeau (TeamB)
Peter Lee

Posts: 3
Registered: 10/18/02
Re: DLL exception problems between D2010 and Xe4  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 26, 2015 7:33 AM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Remy Lebeau (TeamB) wrote:
Peter wrote:

I should be able to pass ... two AnsiStrings to the DLL

Passing an (Ansi/Unicode)String across the DLL boundary is not safe either,
for the same reasons that passing an object is not safe. If the EXE and
DLL are not compiled using the same Delphi version, and are not sharing a
single instance of the RTL, then the (Ansi/Unicode)String's memory will not
be managed correctly, and its internal memory layout may even be incompatible
between the two modules. So will have to pass the (Ansi/Unicode)String data
usin P(Ansi/Wide)Char instead. Or use WideString, which is safe (because
its memory is managed by Windows, not the Delphi RTL).

--
Remy Lebeau (TeamB)

Oops, that I definitely didn't realise. Although I have the DLL working ok will need to re-visit the code and make sure that its bomb proof. Once again thanks for the help, you could have save me a lot of grief, widestring looks like the way.

Peter
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02