When I want to export a class within a DLL, is it the right approach to derive it from an interface and return that interface by an exported function?
//exported dll function, which is used in the exe.
function MyClass_Create: IMyClass;
begin
result := TMyClass.Create;
end;
What about the memory management? Can I than pass in/out different interfaces and strings without worries and crashes?
IMyClass = interface
procedure SetString(aMsg: string);
function GetString: string;
procedure SetClass(aClass: ITestClass);
function GetClass: ITestClass;
end;
Interface references are orthogonal to memory management. Usually you export a function that returns interface reference from dll, and don't care about memory management. With reference counting interfaces you can be sure that object instance that implements interface will be freed in dll too.
Strings are different. It does not matter whether you export interface or export flat functions - the same restrictions applies.
BTW your question title is incorrect, there are no 'interface instances' in Delphi.
Using interfaces like this will ensure that the object implementing the interface will be created and freed on the same heap.
However, this will not solve the problem of dynamic string types being allocated and deallocated on different heaps. There are many possible solutions to this, but in my view the best approach is to use WideString across the module boundary.
The WideString type is a wrapper around the COM BSTR and is allocated on the shared COM heap. You only need to use WideString for the interface. The internals of the implementing classes can use native Delphi strings.
Just as strings present problems so do dynamic arrays. Attempting to pas dynamic arrays across module boundaries is not safe. There is no solution analagous to WideString that is as convenient. You can use variant arrays but that's pretty clunky in comparison to WideString.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With