views:

1237

answers:

4

I have a application and several plugins in DLL files. The plugins use symbols from the application via a export library. The application links in several static libraries and this is where most of the symbols come from. This works fine as long as the application uses a symbol. If the symbol is not used there, I get linker errors when compiling the DLL.

How can I force the export of the symbols only used in the plugins?

In order to trigger the export I've tried something like this:

 class MyClassExporter
 {
  MyClass mInstance;
 public:
  MyClassExporter() {}
 };
 static MyClassExporter TheMyClassExporter;

in one of the static libs the application is made of to force the export, which didn't work.

In response to Greg (thanks for the answer) and to clarify: The class I want to force the export for is MyClass (which has __declspec(...) defined, depending on wether I want to export or import). MyClassExport was my attempt to force the inclusion of unused (in terms of the application) symbols into the app. I want to 'touch' the symbols so that the linker recognizes them as used and includes them into the application so that it can in turn export these to my plugins. Linking the static libs into the plugins is not an option, since they contain singletons which would be duplicated (app and DLLs each have their own copy of static variables).

+1  A: 

You probably want to look at __declspec(export/import)

#ifdef DLL_EXPORTING
#define WHDLL __declspec(dllexport)
#else
#define WHDLL __declspec(dllimport)
#endif

When linking static module into a dll it will only bring in the code that is used. I've never imported stuff from a static lib to simply re export it.
Perhaps you just need to mark it as exportable in the dll when compiling the static lib.

But that reminds me of putting std containers into exported classes and using some trickery in msvc to export the 'instance' of the specialised container. the template code is similar to your static code (in my thinking)

for instance without the template you get warnings the template code is not exported to support the class - this is MSVC specific from my understanding

template class DLL_EXPORTING std::auto_ptr<wxCursor>;
class DLL_EXPORTING imageButton : public wxWindow
{
    std::auto_ptr<wxCursor> m_Cursor;
};
Greg Domjan
I need to import from the static libs and export to the plugins because I have singletons in them which would get duplicated if I'd link them into the DLL (DLLs and app have their own static variables). Your first sentence explains the problem: I'm looking for a way to force the inclusion.
torque
+2  A: 

The /INCLUDE directive can be used to force the MSVC linker to include a symbol. Alternatively, /OPT:NOREF can be used to disable removal of unused symbols in general.

A common approach is to create a single unused function that references all objects exported for your plugins. Then you only need a single /INCLUDE directive for that function.

Judge Maygarden
Tried this out, but didn't work - should the symbols be 'decorated'? Can they contain namespaces?
xtofl
Did it work with /OPT:NOREF? If not, you may have a different problem altogether...
Judge Maygarden
+2  A: 

What I tried out to solve this was this:

  1. build a static library with function void afunction( int ).
  2. build a dll, linked to static lib, exporting afunction.
  3. build an exe, using the afunction symbol.

How? Since the linker can be told to export functions using the __declspec(dllexport) directive, a dll needs no more than declare a to-be-exported symbol thusly.

The lib has a header "afunction.h" and an accompanying cpp file containing the function body:

// stat/afunction.h
namespace static_lib { void afunction(int); }


// stat/afunction.cpp
#include "afunction.h"
namespace static_lib { void afunction(int){ } }

The dll has an include file "indirect.h", containing the declaration of the function to be exported. The dll has a link-time dependency to the static lib. (Linker options: Input/Additional Dependencies: "static_library.lib")

// dll/indirect.h
namespace static_lib {
  __declspec( dllexport ) void afunction(int);
}

The executable has only the indirectly included file:

#include <dll/indirect.h>
int main() { static_lib::afunction(1); }

And guess what? It compiles, links and even runs!

xtofl
A: 

I have tried the solution proposed by xtofl, but it doesn't work: Even though the dll declares afunction with the dllexport directive and has a dependency to the static lib which defines this function, it does not export this symbol unless it is defined in this project. Has anyone else experienced this?