Reputation: 3042
I want to create a DLL with some of the functions in order to make it easier to manager code, update the program etc. I don't want any other programming languages to use my DLL, just Delphi.
So in this case it it safe to pass Strings and objects as arguments? Like this:
function LoadImage(Filename: AnsiString; Bmp32: TBitmap32): Integer;
begin
//
end;
Will such DLL work fine with different versions of Delphi?
Upvotes: 1
Views: 112
Reputation: 2007
AnsiStrings should work fine if you include ShareMem
to the uses section as the first entry (there is a big comment about this topic at the beginning of each new DLL project! Please read it carefully.)
For your question about using objects as arguments to DLL functions/procedures:
This approach is not secure because you can't be sure that the version of used class is the same in both the host app and the DLL!
There is a very nice article about DLLs by Rudy Velthius for more detail information here.
Upvotes: 1
Reputation: 6487
Passing object to DLL is messy (fragile, unadviseable). So much so that I gave up on that a while ago. Now, if I want to pass an object to a DLL, I do it through an interface.
If you intend to keep on this path, there is a few thing you need to know.
First, it most likely (definitely?) won't work for different version of Delphi.
It may not work if you didn't build the EXE and DLL with the exact same compile options.
It might still not work if you compiled with exactly the same compile options.
If you don't build both EXE and DLL with runtime package, weird stuff can happen, like
function Sample(AStrings : TStringList) : Boolean;
var vStrings : TStringList;
begin
vStrings := TStringList.Create;
try
AStrings.Assign(vStrings); //ERROR : Cannot assign a TStringList to a TStringList
finally
vStrings.Free;
end;
end;
This happens because the DLL and the EXE don't have the same class reference. They both have their own definition of TStringList and they are incompatible.
So, depending on what your function do, you would probably need to have the TBitmap32 in a runtime package. And depending on what TBitmap32 does, you would also need to have a runtime package with every classes it uses, directly or indirectly.
There's probably more... I stopped researching that minefield long ago.
Upvotes: 1
Reputation: 613302
Will such DLL work fine with different versions of Delphi?
No, for both strings and classes.
For strings, it can work if you use a shared memory manager, and the Delphi versions have the same implementation for strings. That's not something that changes frequently, so you can often get away with it. And you can often get away with it depending on how the parameter is passed (const, by value, var, etc.) and what the callee does with it.
Let's look at classes now. The layout of the class can vary between different versions of Delphi, and more likely different versions of graphics32.
Even if that were not the case it would not be safe. The reason being the you have two instances of the RTL/VCL. One in the host executable, one in the DLL. When the host executable creates an instance, that instance is expecting to work with the RTL/VCL instance in the host executable. But when you pass it to the DLL and call a non-virtual method, the code that executes is the code in the DLL, which expects the RTL/VCL instance of the DLL.
Packages are designed to solve this problem. Use runtime packages, and you allow all modules to share the same RTL/VCL instance.
Of course packages force all parties to use the same Delphi version. You might not want that. In which case the remaining option for you is to expose the functionality using interfaces.
Upvotes: 5