7

I inherited a huge C++ multi-project solution with many dynamic libraries but without any

__declspec(dllexport)

I learned that one does not necessarily have to insert any dllexport (would be much work) but that one can use a .def file in addition to corresponding .dll instead.

In order to try that I built a "DLL Hello World" project from here, removed the dllexport from the header and...failed desperately. In the words of already cited page, my key question is how to

"[..] use the .def file when building the DLL."

My .def file is (I try the code only with the Add method):

LIBRARY   MathFuncsDll
EXPORTS 
?Add@MyMathFuncs@MathFuncs@@SANNN@Z

How do I use it when building the DLL in Visual Studio 2010 in order to export the Add method?

Finnfalter
  • 732
  • 2
  • 7
  • 22
  • Can you show the prototype to your `Add` function? – cdarke Jan 18 '13 at 15:53
  • `static double Add(double a, double b);`, placed as `public` in class `MyMathFuncs` of namespace `MathFuncs` – Finnfalter Jan 18 '13 at 15:55
  • Are you exporting the class? See http://stackoverflow.com/questions/186232/exporting-dll-c-class-question-about-def-file – cdarke Jan 18 '13 at 16:24
  • No, I don't but thank You for the hint anyway. – Finnfalter Jan 18 '13 at 16:36
  • Do you want to export pure-C interface functions from the DLL? – Mr.C64 Jan 18 '13 at 16:44
  • Sorry, I do not understand Your question, Mr.C64. I use C++. What would be (im)pure? – Finnfalter Jan 18 '13 at 16:46
  • 1
    Win32's [`GetWindowText()`](http://msdn.microsoft.com/en-us/library/windows/desktop/ms633520(v=vs.85).aspx) is an example of a "pure C interface" function exported from a DLL. You use `extern "C"`, you don't use C++ objects at the interface, you don't throw C++ exceptions outside the function, etc. (The implementation can be in C++, but the interface is pure C.) But it seems you want to export a C++ class (static) method... – Mr.C64 Jan 18 '13 at 16:57
  • Thanks a lot for Your effort to teach me, Mr.C64. In this case, interface functions are impure in given projects. – Finnfalter Jan 19 '13 at 08:40

1 Answers1

12

After having passed half a day in front of this problem, I just found the solution: it is described here.

To resume the process of symbol export with .def files in VS2010 using my own words:

  1. Tell VS2010 to compile a dynamic library (.dll). This is done in the Property Page of the library's project.
  2. Craft a module definition file (.def) by using mangled (decorated) names (at least when Your language is C++). If You make use of dllexport You can display already exported symbols of Your .dll as described here. If You haven't anything exported yet, see this post.
  3. Add the .def to the library definition in its Property Page.
  4. Compile
  5. Verify the correctness of Your work, for example with Dependency Walker by opening the dependent file, e.g. .exe. You should see the just compiled library in a dependency tree below the dependent file. There should be no errors or warnings, e.g. no red colour.

If You have further questions concerning .def files, look out for the terminus "Module definition file".

Community
  • 1
  • 1
Finnfalter
  • 732
  • 2
  • 7
  • 22
  • The whole point of __declspec is that you don't have to do 2, 3 and 5. You only really use a .def file if you want to *rename* the exports. – Hans Passant Jan 18 '13 at 18:06
  • 2
    In my case I was **reluctant to add** _dllexport_ in hundreds of files of already existing code. In particular because it may change in the future (not my changes). That code is developped for MinGW, actually. My **hope** is **to automate exports without any code changes.** – Finnfalter Jan 19 '13 at 08:28
  • That naturally leads to the next obvious question: How to determine '_mangled_' names like `?Add@MyMathFuncs@MathFuncs@@SANNN@Z` for arbitrary classes and methods? In my specific case, I cheated: I created a .dll **with** _dllexport_ first, extracted the symbol, then crafted the .def with extracted symbol and, finally, removed _dllexport_ again. How can a _mangled_ name be determined in a general case? – Finnfalter Jan 19 '13 at 08:34
  • 1
    Right, you got it complete backwards. dllexport ensures that the mangled name is correct, even after changes. You could use a map. – Hans Passant Jan 19 '13 at 11:37