The Design of Software (CLOSED)

A public forum for discussing the design of software, from the user interface to the code architecture. Now closed.

The "Design of Software" discussion group has been merged with the main Joel on Software discussion group.

The archives will remain online indefinitely.

Sending parameters to plugins across DLL boundaries

I'm working on a program which has a plugin module capability, and evaluating different methods of sending parameters to the plugins others will be writing.  I'd really like to do something simple like send in an STL map with parameter names as the key and maybe a pointer as the value which can be cast to the appropriate type, but as I understand it sending STL objects across a DLL boundary is not a great idea. 

I've got a workable solution using a few arrays of simple keyword/value structs, but I'd really prefer something a little more general.  Has anybody else done something like this or have any good ideas?
Jon B Send private email
Monday, July 25, 2005
You need to use something with a well-defined binary interface, which is why std::map is unsuitable - its interface is defined at the source level.  Either use a COM interface (like the scripting dictionary) or a binary format (like a null-separated list of key-value pairs).
Jonas Grumby Send private email
Monday, July 25, 2005
The problem with passing STL objects across a DLL boundary is that you have to be using the SAME STL on both sides for it to work at all and even then it's less than ideal. You may also find the template nature of the STL causes problems due to it being difficult to control where memory is allocated and released; allocating memory in the host exe and then deleting it in the DLL is, generally, bad news.

The object that you pass across the boundary doesn't have to be a COM object, though COM solves all the problems that you'll come across it's usually overkill for this particular situation. What I tend to do is create a non template class that is suitable for the intended purpose; in your case it might be a simple wrapper around the map that you want to pass (dont derive from map, wrap it! and don't have any inline member functions in the header file) Next I'd usually create a new DLL to house this object in, though that's not essential. It's useful to have the parameter object available independently of the host exe, and if you have multiple plugin DLLs with the same DLL interface then you cant have the parameter object living in one of the plugins.

Once this is done you can create an instance of your parameter object in your host exe and then simply pass it to the function in your DLL that needs it. As long as you dont allocate your object in the host exe and deallocate it in the DLL you should be fine as far as memory management goes as the allocation and deallocation that goes on inside the parameter object will occur in the context of the DLL in which it lives.

I wrote about this a while back on my blog, though at the time I was taking a slightly more conservative approach than the one I recommend above:
Len Holgate ( Send private email
Tuesday, July 26, 2005
Look at how well-established programs like Photoshop do this. Photoshop just uses a elaborate struct with C callback functions to communicate between the host and the plugin.
Frederik Slijkerman Send private email
Tuesday, July 26, 2005
Create the structure and give it a name, compile it into it's own dll, use the dll in both the main app and the calling applications.

MSVC allows you to define a (qualified?) template class so that it can be exported, however you have the further problem that it is necessary to have the same implementation available not just in one dll and the program to use, but accross the many plugins, thus you need the definition of this shared class to be in a seperate library to be referenced by both.

to avoid trouble as other people have mentioned of mixed stl libraries - in your dll which provided your special interface bits, use 'has a' instead of 'is a'.

class paramlist
  static paramlist newParamlist();

  getParam( ) const;
  setParam( const );
  map * m_p;

Tuesday, July 26, 2005
Another safe way to solve the problem is to use text. You can pass a string where each parameter is separated by new line.

Problem is that you have to provide function to code and decode your text data. And the separator problem might be killing.

Now that I said it, using text does not sound so appropriate for your problem :-)
Philippe Fremy Send private email
Wednesday, July 27, 2005
I've found that creating a serialization layer between "components" is a really nasty design solution.  What you have is a specialized case of the age old "how to pass data between general components" issue.

At my company, so many people want to use XML for crap like this it's ridiculous.  Aaagh!

In any case, I think you basically have two approaches: either consider a "safe" serialization mechanism (strings, generic binary description, XML), or actually create a component around the data being passed around and control the memory management.  I prefer this technique since the layer controls optimization.  But if you can guarantee your plugin behavior is really simple and the plugin will only have read-only access of insignificant data, then wtf, just use a simple safe data type and get the problem solve quickly.
Tristan Juricek Send private email
Sunday, August 21, 2005

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics
Powered by FogBugz