将c ++类导出到DLL,包括外部DLL

时间:2013-07-25 08:56:35

标签: dllexport

所以我试图将一个使用另一个dll类的类导出到一个dll中。一个例子可以更好地解释这种情况。

//aclass.h
class  __declspec(dllexport) aclass{
    public:
        void amethod();
};

_

//aclass.cpp
#include "aclass.h"

void aclass::amethod(){
    std::cout<<"a method"<<std::endl;
}

所以不包含任何外部的编译(aclass.dll)并从其他项目运行,例如

#include <aclass.h>

void main(){
    aclass a;
    a.amethod();

    _getch();
}

当我包含一个外部头文件(附带一个dll和一个lib文件,其路径传递给编译器)时,会出现问题。只要我包含外部标题:

//aclass.h
#include <externalapi.h>
class  __declspec(dllexport) aclass{
    public
    void amethod();
};

甚至没有从externalapi调用任何类函数,当我尝试编译时我得到:

Error 1 error LNK2001: unresolved external symbol __imp__Math_e C:\...\aclass.obj  aclass
Error 1 error LNK2001: unresolved external symbol __imp__Math_pi C:\...\aclass.obj aclass
Error 1 error LNK2001: unresolved external symbol __imp__Math_zero C:\...\aclass.obj aclass
....etc

最初(没有__declspec(dllexport)指令)我会通过以下方式访问它们:

Math::pi;
Math::e;
etc.

因为它们是外部的静态常数。 根据我对dll导出的整个过程的理解,这就是所谓的名称修改(?)。所以有两个问题:

  1. 我应该在语法中更改什么,以便使用原始c ++名称“加载”外部库的函数名称?这必须以某种方式成为可能。到目前为止,我正在开发我的代码,作为一个独立的应用程序,这意味着我没有使用__declspec(dllexport)关键字,我包含相同的头文件,使用完全相同的DLL和lib文件,一切都在编译和运行顺利。显然,上面的代码是我的实际代码的过度简化,以指出问题。
  2. 在我发现的大多数“export to dll”方法中,人们使用__declspec(dllexport)和__declspec(dllimport)。我理解__declspec(dllexport)或多或少告诉编译器将代码的一部分导出到dll,这是有道理的。 __declspec(dllimport)究竟是什么意思。例如,为什么这是第一段代码,我在开头编写,编译并可用作dll而不需要__declspec(dllimport)?
  3. 谢谢你的时间!

2 个答案:

答案 0 :(得分:1)

通常最好有一个根据

导入或导出的条件宏
#ifdef MODULE1
#define MODULE1_DECL __declspec(dllexport)
#else
#define MODULE1_DECL __declspec(dllimport)
#endif

这样您可以导出要导出的函数等,并导入要使用的内容。 例如,请参阅此SO post
您项目中的#define MODULE1(可能是设置)将导出定义,并使用MODULE1_DECL定义,而不是在代码中明确放置__declspec(dllimport)__declspec(dllexport)。阅读manual了解更多详情。
Name mangling恰好发生在C ++中:它表示名称空间,函数重载等参数用于消除歧义。

答案 1 :(得分:1)

__declspec(dllimport)告诉编译器该函数将使用导入LIB从DLL导入,而不是在不同的OBJ文件或静态LIB中找到。

BTW:听起来你根本不需要DLL。 DLL专门用于在编译之后交换库,而不必重新编译应用程序,或者用于在应用程序之间共享大量目标代码。如果您只想在不同项目之间重用一组代码而不必为每个项目编译它们,那么静态库就足够了,而且更容易推理。