C++ 用dll链接静态库的正确方法

C++ 用dll链接静态库的正确方法,c++,visual-c++,dll,visual-studio-2013,declspec,C++,Visual C++,Dll,Visual Studio 2013,Declspec,我的项目通过几个静态库构建,这些库应该链接到主dll库,从而获得一个dll 使用\uuuu declspec(dllexport)属性不会导致静态库的指定函数出现在dll中,库根本不与dll链接 然后,我尝试将每个库构建为共享库,以获取导出函数的正确名称,并基于它们创建.def文件。使用导致结果的.def文件 \uuu declspec(dllexport)和.def文件在我的情况下是否应该同样起作用 是否可以从源代码生成.def文件?因为我有C++代码,我自己不能编写.DEF文件,因为API中

我的项目通过几个静态库构建,这些库应该链接到主dll库,从而获得一个dll

使用
\uuuu declspec(dllexport)
属性不会导致静态库的指定函数出现在dll中,库根本不与dll链接

然后,我尝试将每个库构建为共享库,以获取导出函数的正确名称,并基于它们创建.def文件。使用导致结果的.def文件

  • \uuu declspec(dllexport)
    .def文件
    在我的情况下是否应该同样起作用

  • 是否可以从源代码生成.def文件?因为我有C++代码,我自己不能编写.DEF文件,因为API中有MULFIN和ION类,上面描述的方法与临时生成的DLL不一致。 更新 我想详细解释一下我的项目结构。该解决方案由几个项目(模块)组成


    每个子项目都弱地依赖于其他子项目,让我们假设它们之间没有清晰的联系。每个模块都有自己的公共接口。我希望将所有模块都作为单个动态库,因此我的工件是
    动态库.dll
    ,但实际上静态库不与之链接。

    静态库不应包含任何
    \u declspec
    \u属性((dll…)
    内容。它们不过是多个对象文件(通常是
    *.obj
    *.o
    ),组成一个单独的文件

    要使用这样的库(无论是在
    .exe
    还是
    .dll
    中),您所需要做的就是包含适当的头并将它们链接起来—使用Visual Studio,这非常简单

    首先,您需要知道1)静态库的位置和2)它们的确切名称。转到“项目属性”,然后单击“常规”
    Target name
    包含输出文件的名称,而
    output directory
    指示将把
    .lib
    放在哪个文件夹中

    注意:每个项目的路径可能不同!对于多项目解决方案,我总是将其设置为公共路径以避免配置问题

    现在,转到将使用此库的项目的属性(与之链接)。转到
    链接器
    ->
    输入
    ,然后将
    .lib
    的名称添加到
    其他依赖项
    (条目用分号分隔):

    您需要添加要链接的所有库。此外,放置这些库的文件夹必须添加到
    链接器
    ->
    常规
    ->
    其他库目录中。如果所有
    .lib
    都放在同一个位置-好,否则将它们复制到共享位置或将多个条目添加到
    其他库目录
    列表中

    最后一件事——记住,您还需要包含带有您想要使用的函数和对象声明的头。基本的事情,我知道,但必须提到


    更新

    尝试在外部产品中使用dll库时未解析的外部

    你的问题根本与链接无关。问题是,您误解了链接静态库的作用

    我猜,报告为未解析的函数不会被您的
    DLL
    使用,对吗?但你希望他们在里面,对吗

    当您的
    DLL
    引用外部内容(如函数或变量)时,将在链接时解析该内容以及所有依赖项但仅此而已。如果您的静态库有一个名为
    print\u sample\u string()
    的函数,但您的
    DLL
    没有使用它,则它不会附加到
    DLL
    图像。仔细想想,为什么会这样

    更重要的是,没有显式地
    dllexport
    ed的函数无论如何都不会可见。默认情况下,函数具有外部存储—因此基本上,它们是私有的
    DLL
    内容

    因此,为了直接回答您的问题,如果您需要使用
    静态库1.lib
    中的函数/变量,请将其附加到客户端应用程序,就像您现在将其附加到
    动态库一样。没有别的办法(*)


    (*)确切地说,是有的。您可以在
    DLL
    中创建中间函数,将其导出并在内部调用所需函数:

    动态库中的某个地方

    DLL_EXP_IMP long CallFunctionFromA_Lib()
    {
         return some_function(); //this function is from static_lib1.lib
    }
    
    long result = CallFunctionFromA_Lib(); //internally this will call function from static_lib1.lib
    
    .exe
    中的某处:

    DLL_EXP_IMP long CallFunctionFromA_Lib()
    {
         return some_function(); //this function is from static_lib1.lib
    }
    
    long result = CallFunctionFromA_Lib(); //internally this will call function from static_lib1.lib
    

    然而,我无法想象,为什么您要这样做,而不是简单地链接
    A.lib
    并直接使用它。

    Raymond Chan解释了这种行为,最好的解决方案就是使用def文件。至于如何为静态库自动生成它,讨论看起来是一个很好的起点。

    谢谢!但我有相同的配置。我的问题是库之间没有相互使用代码,每个库都是单独的模块,使用自己的公共接口,因此链接器忽略了其他静态库,除了主要的oneUpdate问题,其中包含关于您有哪些库、您希望使用哪些库(以及哪些库)以及您得到的错误的确切信息。我不明白除了主库之外,
    链接器忽略其他静态库是什么意思。问题:你说的
    […]库根本没有与dll链接。您是否在
    dynamic_-lib
    或另一个使用dynamic_-lib的项目中遇到错误?尝试在外部prodjectsLink中使用dll库时,此错误是否为未解析的外部[…]
    未解析的外部