views:

2592

answers:

4

I want to use implicit linking in my project , and nmake really wants a .def file . The problem is , that this is a class , and I don't know what to write in the exports section . Could anyone point me in the right direction ?

The error message is the following :

NMAKE : U1073: don't know how to make 'DLLCLASS.def'

P.S: I'm trying to build using Windows CE Platform Builder .

+7  A: 

If I recall correctly, you can use __declspec(dllexport) on the class, and VC++ will automatically create exports for all the symbols related to the class (constructors/destructor, methods, vtable, typeinfo, etc).

Microsoft has more information on this here.

Greg Hewgill
A: 

The solution is the following :

  • since a class is exported,you also need to add the exported methods in the .def file

  • I didn't find out how to export a constructor , so I went with using a factory method ( static ) , which will return new instances of an object

  • the other functions will be exported by adding normal exporting declaration in the .def file

Hope someone will benefit from this information .

Vhaerun
this is not a solution, but a workaround. You _can_ add the constructor symbol in the .def file.
xtofl
All three bullet points are untrue: see __declspec above.
EJP
+2  A: 

You can always find the decorated name for the member function by using dumpbin /symbols myclass.obj

in my case

class A {
   public:
     A( int ){}
};

the dumpbin dump showed the symbol ??0A@@QAE@H@Z (public: __thiscall A::A(int))

Putting this symbol in the .def file causes the linker to create the A::A(int) symbol in the export symbols.

BUT! as @paercebal states in his comment: the manual entry of decorated (mangled) names is a chore - error prone, and sadly enough, not guarenteed to be portable across compiler versions.

xtofl
Thank you very much ! This may be the solution I've been looking for .
Vhaerun
+2  A: 

I've found the best route to be an abstract factory.

Start by defining a purely virtual base class. This is a class with no implementation, a purely virtual interface class.

You can export this virtual base "abstract interface" class, but there's no real reason to do so. When the caller uses it, they will be using it through a pointer (PImpl, or Pointer to Implementation) so all the caller knows about is a simple memory address. A Def file, while a teensy bit more work to keep up with, provides benefits beyond what __declspec(dllexport) can attain. What benefits, you ask? We'll get to that, you just wait.

Have your real class publicly inherit from the virtual base. Now create a factory method to construct your object and a "release"ish callable destructor to perform cleanup. Name these methods something like "ConstructMyClass" and "ReleaseMyClass". Please, please replace "MyClass" :-)

Those factory / release methods should take only POD types if they need any paramaters (plain-old-data: integer, char, etc.). The return type should be your virtual abstract interface base class -- or rather, a pointer to it.

IMyClass* CreateAnObjectOfTypeIMyClass();

Perhaps it's now obvious why we need the virtual base class? Since the virtual interface class has no implementation, it's essentially all POD types (sort-of) so the "datatype" of the class can be understood by most callers like Visual Basic, C or vastly different C++ compilers.

If you're sufficiently fancy, you can get around the need for a "manual release" method (sorry, had to do it). How? Manage your own resources in the class through smart-pointers and a pImpl type of architecture so when the object dies, it will clean up after itself. Doing so means your class is, in the immortal words of our saint and saviour Scott Meyers, "easy to use correctly and hard to use incorrectly" by letting the caller disregard the need to clean up. Let those among us who have never forgotten to call ".close" cast the first stone.

Maybe this architecture sounds familiar? It should, it's basically a micromachine version of COM. Well, sort-of, at least the concept for interface, factory construction and release.

In the end you've exported the interface for your class, made (and exported) Create and Destroy methods, and now callers can invoke your PleaseConstructMyClass factory function to have your DLL return a fully constructed, fully implemented and fully baked object under the guise of its interface. They can call down to all the public methods of your class (at least the ones in your abstract virtual interface) and do all the fun stuff.

When they are finished with the object which was returned by the factory function, then they can call a "ReleaseMyClass" function to ask your DLL to clean up the object's resources, or you can help them along by making your class clean up itself, making the "ReleaseMyClass" method redundant and useless.

If anyone's interested in the specific gains & tradeoffs for using the Def file and the interface (besides my blind say-so), please pipe up and we can dig deeper.

Don't you just love this stuff?

Allbite