4

I've inherited a C++ project, and I need to transform it in a DLL, to use it in other projects.

The code is framed in a Visual Studio 2010 solution. I'm able to compile it and generate a DLL file, but there's no associated lib file. I'm not a Windows developer, but seems that I need to export the functions that I want to be used, and there are two ways:

First option would imply to manually add __declspec(ddlexport) in front of every class or function I want to export. As there are a lot of classes, and I don't have the control of all the apps which are going to link against the library, the second option (DEF files) looks more promising.

Is there any way to generate a DEF file from existing DLL file? I've tried different solutions:

  • Using expdef. It just crash with no info at all.
  • Using dumpbin. I don't see functions names. Just this:

    File Type: DLL

    Summary

        1000 .data
        2000 .idata
       18000 .rdata
        5000 .reloc
        1000 .rsrc
       98000 .text
       48000 .textbss
    

Nothing more. I guess that means I'm not exporting anything. But, that's exactly what I'm trying to do. How do I do it?

Jorge Arévalo
  • 2,858
  • 5
  • 36
  • 44
  • Maybe this can help you: http://stackoverflow.com/questions/14402415/export-function-from-dll-in-visual-studio-2010-using-def – Matz Jan 29 '14 at 15:02
  • 4
    First job is to avoid exporting *everything*. A public interface for a DLL needs to be *designed*, it is not a random act of slapping attributes into code. If you do have C++ classes that need to be exported, beware of the considerable dangers in doing this, then you very strongly favor using __declspec(dllexport). Doing it with a DEF file is cruel and unusual punishment and bound to go wrong. – Hans Passant Jan 29 '14 at 15:06
  • Sorry for my dumb-level questions. When I declare a class, I have some public attributes and methods. So far, so good. Now, let say we have 100 classes. Each class has its own public attributes and members. In my (probably naive) approach, I just want to pack the code in a library (a DLL file), and let other programs to call just the public interface of each class. So, if I used "public" to define this interface, why do I need another mechanism to say which parts must be considered as public and so exposed to be called? – Jorge Arévalo Jan 30 '14 at 12:16

2 Answers2

2

Why not specify creation of an implib in your project and recompile. Here is the relevant info. This will export everything, and your other projects can link against the implib (a .lib file) to use this dll. If, on the other hand, you want to avoid exporting everything in the DLL, then you need to create an API (preferably C for compatibility with non-Microsoft compilers, if this is even a case) and then export only those functions. This can be done by creating a small text file, renaming it .def and adding it to the project. This file's format is well-documented in MSDN but the minimum you need is something like this:

LIBRARY MyDLLName
EXPORTS
    function1
    function2
    ....

The above would require using the exact names of the functions in the code. These functions should be declared external "C" to avoid C++ name mangling, and WINAPI to specify calling convention for 32bit code. However your exported names can be more 'readable' if you write it like this:

LIBRARY MyDLLName
EXPORTS
    exportedName1=internalFunctionName1
    exportedName2=internalfunctionName2
    ....

For more information on the syntax see here.

DNT
  • 2,356
  • 14
  • 16
  • I recently added a project and compiled..But now. when i try to use a DEF file it always says LINK : fatal error LNK1104: cannot open file '/DEF:C:\d.def .. – Ragav Dec 16 '14 at 14:47
  • This error means "Cannot open filename" - place your .def file where the rest of the sources are and add it to the project. Then specify in the settings that you want to use a .def file. The filename reported in the error is a bit strange. Seems you tried to add it on the command line? – DNT Dec 16 '14 at 23:24
2

After repeatedly coming across this problem for a couple of years I've today found a solution. It's a little hacky, but it actually might be the best possible way with Visual Studio.

Since you don't want to export EVERY possible symbol (especially since your DLL may include large static libraries itself), and you can't edit the files with symbols you want to have available (for me it's because they're 3rd party libraries which must be statically linked to follow their usage pattern), and DEF is the best solution.

If we have:

  • Application (EXE)
  • Library (DLL)
  • Library has .DEF file which means that when you build, symbols listed in the .DEF will be exported to the Library .DLL and listed in the .LIB file.
  • .DEF file is empty
  • Application links Library's LIB file

NOW BUILD!

OK, we get a lot of linker errors... Linker errors

Now go to the "Output" tab, and notice that within the text of the output is the symbol names at the end of each linker error line:

Linker error text

We can create a little script with takes the last 'word' of every line, takes off the brackets, and then put that in your DEF file. And it works!

Like I said it's a little hacky (since you only end up with the symbols used by the Application at that time). But actually since you don't want to export everything, and you might need symbols in the libraries which that library statically links, it's probably the most accurate way of going about this.

(NB : In my case it's mostly a problem with trying to get the plugin DLL have access to symbols in the application EXE)

Elliot Woods
  • 834
  • 11
  • 20