Jorge Arévalo
Jorge Arévalo

Reputation: 2998

How to generate DLL from existing C++ code using DEF file in Visual Studio 2010

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:

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?

Upvotes: 4

Views: 9327

Answers (3)

DaveB
DaveB

Reputation: 37

For Visual Studio 2019, this worked for me...

Build twice... first time without a DEF file. Then from VStudio cmd line window (will refine and add as extra cmd lines in the project), do these steps. First run

DUMPBIN /EXPORTS mydll.dll >myexports.txt

Then use a PHP script to process txt and create a DEF file. In the PHP script, I stripped header and trailer lines, added a new two line header (LIBRARY "mydll" and EXPORTS), and used this regex to replace all body lines...

$regexPattern = '/^\s*(\d+)\s+\S+\s+\S+\s+(\S+).*$/';
$regexReplacement = '\2 @\1 NONAME';

Then build a second time with just these two changes in vcxproj file...

<ModuleDefinitionFile>$(OutDir)$(TargetName).DEF</ModuleDefinitionFile>
<AdditionalOptions>/IGNORE:4197 %(AdditionalOptions)</AdditionalOptions>

Putting the generated DEF in the output BIN folder means you can have a distinct DEF per configuration if doing multiple build configs. Also note the /IGNORE:4197 is only used in the second build because unless you remove the exports from the declspec's you'll now get a pair of each and many warnings in the second build.

Check the new DLL using strings64.exe or Notepad++ to view the binary and search to see the strings in context. Still will find lots of strings from embedded string constants etc. They need attention... if someone has a good method please add a link to it.

Upvotes: 0

Elliot Woods
Elliot Woods

Reputation: 844

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)

Upvotes: 2

DNT
DNT

Reputation: 2395

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.

Upvotes: 2

Related Questions