неразрешенный внешний символ для __declspec (dllimport) при использовании dll для экспорта класса - PullRequest
16 голосов
/ 17 марта 2012

Я хочу определить производный класс на основе экспортированного класса 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)" (__imp_??1DllObject@ADAI@@UAE@XZ) referenced in function "public: virtual __thiscall MyClass::~MyClass(void)" (??1MyClass@@UAE@XZ)
2>Test_Entry.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) protected: __thiscall ADAI::DllObject::DllObject(void)" (__imp_??0DllObject@ADAI@@IAE@XZ) referenced in function "public: __thiscall MyClass::MyClass(void)" (??0MyClass@@QAE@XZ)
2>c:\Users\Adai\Documents\Visual Studio 2010\Projects\Test_Main\Debug\Test_Main.exe : fatal error LNK1120: 2 unresolved externals

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

Когда я меняюсь

    class MYDLL_API DllObject

до

    class __declspec(dllexport) DllObject 

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

1 Ответ

6 голосов
/ 19 марта 2012

Причина встраивания.

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

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

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

...