如何使用Visual Studio 2010中的DEF文件从现有C ++代码生成DLL

时间:2014-01-29 14:06:02

标签: c++ visual-studio-2010 dll dllexport

我继承了一个C ++项目,我需要在DLL中对其进行转换,以便在其他项目中使用它。

代码以Visual Studio 2010解决方案为框架。我能够编译它并生成一个DLL文件,但是没有关联的lib文件。我不是Windows开发人员,但似乎我需要导出我想要使用的功能,有两种方法:

第一个选项意味着在我要导出的每个类或函数前面手动添加__declspec(ddlexport)。因为有很多类,并且我没有控制所有要链接到库的应用程序,所以第二个选项(DEF文件)看起来更有前途。

有没有办法从现有的DLL文件生成DEF文件?我尝试过不同的解决方案:

  • 使用expdef。它只是崩溃而没有任何信息。
  • 使用dumpbin。我没有看到函数名称。就是这样:

    文件类型:DLL

    摘要

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

没有更多。我猜这意味着我没有出口任何东西。但是,这正是我想要做的。我该怎么做?

2 个答案:

答案 0 :(得分:2)

为什么不在项目中指定implib的创建并重新编译。 Here是相关信息。 这将导出所有内容,您的其他项目可以链接implib(.lib文件)以使用此dll。另一方面,如果您想避免导出DLL中的所有内容,那么您需要创建一个API(最好是C与非Microsoft编译器兼容,如果是这种情况),然后只导出那些函数。这可以通过创建一个小文本文件,将其重命名为.def并将其添加到项目中来完成。这个文件的格式在MSDN中有详细记录,但您需要的最小值是这样的:

LIBRARY MyDLLName
EXPORTS
    function1
    function2
    ....

以上内容需要使用代码中函数的确切名称。这些函数应声明为外部“C”以避免C ++名称错位,而WINAPI则指定32位代码的调用约定。 但是,如果您这样编写,导出的名称可以更“可读”:

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

有关语法的详细信息,请参阅here

答案 1 :(得分:1)

在反复遇到这个问题几年之后,我今天找到了解决方案。它有点hacky,但它实际上可能是Visual Studio的最佳方式。

由于您不想导出每个可能的符号(特别是因为您的DLL本身可能包含大型静态库),并且您无法使用您想要的符号编辑文件(对我而言) #39; s因为他们的第三方库必须静态链接以遵循其使用模式),DEF是最好的解决方案。

如果我们有:

  • 申请表(EXE)
  • 图书馆(DLL)
  • 库具有.DEF文件,这意味着在构建时,.DEF中列出的符号将导出到库.DLL并列在.LIB文件中。
  • .DEF文件为空
  • 应用程序链接库的LIB文件

NOW BUILD!

好的,我们收到了很多链接器错误...... Linker errors

现在转到"输出"选项卡,并注意在输出文本中是每个链接器错误行末尾的符号名称:

Linker error text

我们可以创建一个带有最后一个字的小脚本'每行,取下括号,然后将其放入DEF文件中。它有效!

就像我说它有点hacky(因为你当时只得到了应用程序使用的符号)。但实际上,既然您不想导出所有内容,并且您可能需要库中静态链接的符号,那么它可能是最准确的解决方法。

(注意:在我的情况下,尝试让插件DLL访问应用程序EXE中的符号主要是一个问题)