Подтвердить что ты не робот

Неразрешенный внешний символ для __declspec (dllimport) при использовании dll для экспорта класса

Я хочу определить производный класс на основе экспортированного класса dll. Базовый класс определен в проекте A, а производный класс - в проекте B.

Во-первых, в проекте A определяется препроцессор MYDLL_BUILD. И я использую файл заголовка для указания экспорта/импорта:

    #if !defined(MYDLL_BUILD)
    #   pragma comment(lib, "myDll.lib")
    #endif

    #if defined(MYDLL_BUILD)
    #   define MYDLL_API __declspec(dllexport)
    #else
    #   define MYDLL_API __declspec(dllimport)
    #endif

Затем я определяю базовый класс:

class MYDLL_API DllObject
{
public:
    virtual ~DllObject() {}
protected:
    DllObject() { m_count = 3; }
private:
    int m_count;
};

В проекте B препроцессор MYDLL_BUILD не определен. Вот производный класс:

class MyClass : public DllObject
{
public:
    ~MyClass(){}
    MyClass() { m_data = 20; }
private:
    int m_data;
}; 

Я включил файл dll и lib, но все же получаю неразрешенную ошибку внешнего символа:

2>Test_Entry.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: virtual __thiscall ADAI::DllObject::~DllObject(void)" ([email protected]@@[email protected]) referenced in function "public: virtual __thiscall MyClass::~MyClass(void)" ([email protected]@[email protected])
2>Test_Entry.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) protected: __thiscall ADAI::DllObject::DllObject(void)" ([email protected]@@[email protected]) referenced in function "public: __thiscall MyClass::MyClass(void)" ([email protected]@[email protected])
2>c:\Users\Adai\Documents\Visual Studio 2010\Projects\Test_Main\Debug\Test_Main.exe : fatal error LNK1120: 2 unresolved externals

Я искал в Интернете, большинство ответов утверждают, что lib отсутствует. Но эти инструкции не решают мою проблему.

Когда я меняю

    class MYDLL_API DllObject

к

    class __declspec(dllexport) DllObject 

Решение компилируется без ошибок. Я действительно не понимаю причину. Кто-то может помочь? Заранее спасибо.

4b9b3361

Ответ 1

Причина заключается в inlining.

Короче говоря, чтобы сделать встроенные функции возможными, С++ должен допускать включение и компиляцию одного и того же определения функции в нескольких единицах компиляции (в основном .cpp файлы) без возникновения ошибок. Компилятор может, но не должен испускать код для любого из этих определений. Затем линкеру разрешено выбирать одну копию.

Это усложняет создание dll, потому что вам нужно экспортировать ровно одну копию, но компилятор не знает, какая именно копия является правильной. В этом случае, добавив некоторый код в DllObject.cpp, вы сделали код испускания компилятора для DllObject, а у компоновщика была некоторая копия DllObject::~DllObject для экспорта.

Я не могу дать вам более подробное объяснение вашего конкретного случая, потому что я не знаю полных исходных и компиляционных параметров для вашего проекта.