views:

87

answers:

2

I have got a DLL and a program, both written with Delphi 2007. The program passes an interface, which descends from IInterface and does not have a GUID (so no COM here) to the DLL which stores it for later use.

This seems to work fine but sometimes I get access violations when the program is closed and the DLL is unloaded. I am not sure about the reason for these AVs. It could be possible that the interface gets out of scope and through reference counting the underlying object, which resides in the program's context, gets freed causing memory corruption because there are two different memory managers involved.

I am not using sharemem and I don't want to for various reasons (one being that there are other programs that are not written in Delphi might want to use that DLL).

I know that I should not pass Strings, open arrays and objects in this manner, but should interfaces work?

+2  A: 

Yes, that should work just fine if it's all Delphi. You do have to make sure to compile both if the interface changes. C++ compilers seems to be compatible, but do watch out for other compilers.

Normally a reference count reaching zero causes the creator of the object to free it. No problems in different memory managers there.

What might be the problem is that your dll still has a reference to an object through an interface and calls IUnknown.Release to lower the reference count when it does not need it anymore. If for some reason the referenced object is already freeed you would get AVs. Make sure all the references (double check the global variables) to objects through references are removed before closing the application.

The debug options of FastMM might help you find your problem.

Lars Truijens
A: 

There's nothing wrong with passing interfaces to and from DLLs. That's exactly what you're doing every time you use an interface from the Windows API, after all. Therefore, your problem lies deeper.

Lacking a GUID is a simple problem to fix. Simply press Ctrl+Shift+G. Then you have no barriers to using COM. All interface-related stuff in Delphi becomes easier when your interfaces have GUIDs, even when you're not using COM.

If your DLL were a COM DLL, then the host program would be able to check whether it's safe to unload the DLL yet. Delphi's COM framework automatically keeps track of whether there are still objects from that DLL active. When the host wishes to unload the DLL, it asks the DLL whether that's safe to do.

Your object should be a COM object. The host program will create instances of your object with the OS standard CoCreateInstance function, using the GUID of your object. Your DLL will be registered with the OS already, so CoCreateInstance will know to load your DLL automatically and call the right functions in it to instantiate your class. (If you're writing the host, too, then just use Delphi's CreateComObject function instead.)

Rob Kennedy
Sorry, I meant to write GUID rather than GUI. Of course not having a GUI does not prevent me from using COM, but having interfaces without GUIDs does.
dummzeuch
Ah, that makes more sense. I've updated my answer accordingly.
Rob Kennedy