2014-01-29 67 views
4

我已经继承了一个C++项目,并且需要将它转换为DLL,才能在其他项目中使用它。如何使用Visual Studio 2010中的DEF文件从现有的C++代码生成DLL

该代码是在Visual Studio 2010解决方案中构建的。我能够编译它并生成一个DLL文件,但没有关联的lib文件。我不是一个Windows 8开发者,但目前看来,我需要出口,我想使用的功能,有两种方式:

第一个选择意味着在我想导出的每个类或函数前面手动添加__declspec(ddlexport)。由于有很多类,而且我没有控制所有将与库链接的应用程序,所以第二个选项(DEF文件)看起来更有希望。

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

  • 使用expdef。它只是在没有任何信息的情况下崩溃。
  • 使用dumpbin。我没有看到函数名称。就在:

    文件类型:DLL

    摘要

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

罢了。我想这意味着我不会输出任何东西。但是,这正是我想要做的。我该怎么做?

+0

也许这可以帮助你: http://stackoverflow.com/questions/ 14402415/export-function-from-dll-in-visual-studio-2010-using-def – Matz

+4

第一份工作是避免导出* everything *。一个DLL的公共接口需要被设计*,这不是一种将属性代码化的随机行为。如果您确实需要导出C++类,请注意这样做的相当大的危险,那么您非常希望使用__declspec(dllexport)。用DEF文件做这件事是残忍和不寻常的惩罚,一定会出错。 –

+0

对不起,我的哑巴级问题。当我声明一个类时,我有一些公共属性和方法。到现在为止还挺好。现在,假设我们有100个课程。每个班级都有自己的公共属性和成员。在我的(可能是天真的)方法中,我只想将代码打包到一个库(一个DLL文件)中,让其他程序只调用每个类的公共接口。所以,如果我使用“public”来定义这个接口,为什么我需要另一种机制来说明哪些部分必须被视为公共的并且被暴露以被调用? – jorgeas80

回答

1

经过几年的反复碰到这个问题,我今天找到了一个解决方案。这有点冒险,但它实际上可能是Visual Studio最好的方式。

由于您不想导出每个可能的符号(特别是因为您的DLL本身可能包含大型静态库),并且您不能编辑带有符号的文件(对于我来说,这是因为它们'需要静态链接以遵循其使用模式的第三方库),DEF是最佳解决方案。

如果我们有:

  • 应用程序(EXE)
  • 库(DLL)
  • 图书馆有DEF文件,这意味着当你构建,在.DEF上市符号将出口Library .DLL并在.LIB文件中列出。
  • DEF文件是空
  • 应用链接库的库文件

现在生成!

OK,我们得到了很多的链接错误的... Linker errors

现在到“输出”选项卡,并注意输出的文本中在每个连接器末端的符号名错误行:

Linker error text

我们可以创建一个小脚本需要每一行的最后一个“字”,起飞括号,然后把在您的DEF文件。它的工作原理!

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

(注:对我来说,它主要是试图让插件DLL可以访问应用程序中的EXE符号问题)

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

+0

我最近添加了一个项目并进行了编译。但现在。当我尝试使用DEF文件时,它总是说LINK:致命错误LNK1104:无法打开文件'/DEF:C:\d.def .. – Ragav

+0

此错误意味着“无法打开文件名” - 将您的.def文件放在其余位置的来源是,并将其添加到项目中。然后在设置中指定要使用.def文件。错误中报告的文件名有点奇怪。似乎你试图将它添加到命令行上? – DNT

相关问题