首页 文章

DLL中指定的接口编译

提问于
浏览
0

编译类时,我遇到了一个链接问题,该类是从另一个DLL的接口派生而来的 . 这是代码 . 我有一个c接口(抽象类),在DLL中指定如下:

// ============================ Source DLL
// header IFace.h"
#ifdef MY_EXPORTS
#define MY_API __declspec(dllexport)
#else
#define MY_API __declspec(dllimport)
#endif

class MY_API IFace
{
public:
    virtual ~IFace() {};
    virtual bool Foo() = 0;
};

// ============================ My DLL
// header
#ifdef MY_EXPORTS22
#define MY_API22 __declspec(dllexport)
#else
#define MY_API22 __declspec(dllimport)
#endif

#include "IFace.h"

class MY_API22 MyClass_Mock : public IFace
{
// IFace
public:
virtual ~MyClass_Mock() {};
virtual bool Foo() ;
};

// cpp file
bool MyClass_Mock::Foo()
{
    return true;
}

当我编译我的DLL,实现接口IFace时,我得到链接器错误:

  • 错误LNK2019:未解析的外部符号"__declspec(dllimport) public: __cdecl IFace::IFace(void)"

  • 错误LNK2019:未解析的外部符号"__declspec(dllimport) public: __cdecl IFace::IFace(class IFace const &)"

  • 错误LNK2019:未解析的外部符号"__declspec(dllimport) public: class IFace & __cdecl IFace::operator=(class IFace const &)"

  • 错误LNK2001:未解析的外部符号"__declspec(dllimport) public: class IFace & __cdecl IFace::operator=(class IFace const &)"

当我明确定义(或在C 11中删除)复制ctor和赋值运算符时,我仍然有默认ctor和dtor的错误 .

don't 想要链接源DLL的.lib文件,因为我想稍后通过LoadLibrary动态加载它 . 我该如何解决这个链接问题?

2 回答

  • 0

    class IFace 更改 class MY_API IFace .

    如果指定 MY_API ,则源DLL将不会导出 IFace ,因为它没有定义 . 另一方面,我的DLL将尝试从源DLL导入 IFace ,但它将失败,因为没有 IFace 的导出定义 .

    如果删除 MY_API ,当我的DLL尝试使用 IFace 时,声明它的头文件就足够了(即 IFace.h ) .

  • 0

    创建导出接口的DLL是一个有问题的领域 .

    C类没有标准的ABI,并且不能保证该类(代码兼容)与不同的编译器是二进制兼容的 .

    在Windows上有一种标准的半形式,其中类与COM对象匹配,并且可以认为是兼容的 .

    内存管理

    在Windows上 malloc / freenew / delete 在运行时中实现 . 这可能是共享运行时(例如msvcr120.dll),也可能是二进制(.dll,.exe) . 如果在一个运行时(静态库)中调用 new 而在另一个运行时调用 delete ,则会发生崩溃(不同的堆被称为免费) .

    要避免这种情况,请使用静态构造函数来构建类,并使用 virtual deletor或使用引用计数 .

    避免实施

    virtual ~IFace() {};
    

    上面的代码创建了在头文件中定义的代码,该代码被绑定到调用者 . 如果此代码与实现不兼容,则可能会调用错误的代码 . 要确保仅调用虚拟接口,您需要将接口类限制为可见功能,而不是实现 .

    class IFace {
      public:
        virtual Delete() = 0;
        virtual Method1() = 0;
    ...
    };
    

    IFace * MYAPI构造函数();

    实施

    class MY_API IFace
    {
      public:
        virtual bool Foo() = 0;
        virtual void Delete() = 0;
    };
    
    
    IFace * MY_API22 MyConstructor()
    
    
    class MY_API22 MyClass_Mock : public IFace
    {
    // IFace
    public:
      virtual void Deletor() { delete this };
      virtual bool Foo() ;
    };
    
    // cpp file
    bool MyClass_Mock::Foo()
    {
        return true;
    }
    IFace * MyConstructor()
    {
         return new MyClass_Mock;
    }
    

相关问题