C ++ DLL-Linking UnResolved Externals - PullRequest
       14

C ++ DLL-Linking UnResolved Externals

4 голосов
/ 17 апреля 2010

У меня довольно большой проект Core, с которым я работаю, я пытаюсь адаптировать его для использования созданного мной движка DLL, я получаю кучу ошибок, таких как:

неразрешенный внешний символ "private: static class

При включении некоторых заголовков из Ядра в DLL класс экспортируется через __declspec (dllexport), но любой заголовок со статическими членами выдает кучу ошибок, касающихся статических членов.

Это довольно большой проект, я не могу бегать вокруг, удаляя каждый член статического класса, который я вижу, есть ли что-нибудь подобное?

Базовый пример импортируемого класса:

class __declspec(dllexport) MyClass
{
    public:
        static bool m_someVar;
}

Для ясности, я бы просто хотел сказать, что m_someVar определен / объявлен (забудьте термин) в файле реализации классов

Ответы [ 3 ]

7 голосов
/ 18 апреля 2010

Когда вы компилируете Core, вы хотите, чтобы эти функции были dllexport; Однако, когда вы компилируете DLL, вы хотите, чтобы они были dllimport. В вашем случае вы всегда определяете их как dllexport, поэтому, когда вы связываете DLL, она жалуется, что вы объявили функцию (и даже сказали, что экспортируете ее), даже не определив ее.

Решение простое. Вместо __declspec ing вручную создайте макрос, основанный на том, являетесь ли вы Core или DLL:

#ifndef I_AM_A_DLL
#define EXPORT __declspec(dllexport)
#define IMPORT __declspec(dllimport)
#else
#define EXPORT __declspec(dllimport)
#define IMPORT __declspec(dllexport)
#endif

Используйте EXPORT для функций в Core и IMPORT для функций во внешних DLL:

class EXPORT MyClass
{
    public:
        static bool m_someVar;
}
2 голосов
/ 17 апреля 2010

Используя ваш сниппет и запустив Dumpbin.exe / exports на DLL, вы получите такой вывод:

1    0 0001107D ??4MyClass@@QAEAAV0@ABV0@@Z = @ILT+120(??4MyClass@@QAEAAV0@ABV0@@Z)
2    1 00017000 ?m_someVar@MyClass@@2_NA = ?m_someVar@MyClass@@2_NA (public: static bool MyClass::m_someVar)

Обратите внимание, что экспорт для статического члена существует, но имеет немного отличающееся имя от вашего. Если я запускаю ваше имя экспорта через undname.exe, я получаю:

Undecoration of :- "?m_someVare@MyClass@@0EA"
is :- "private: static unsigned char MyClass::m_someVare"

Обратите внимание на разницу. У вас есть злой макрос в вашем целевом проекте. Исправьте свою проблему, добавив это в заголовочный файл:

#undef bool

Это может иметь некоторые побочные эффекты:)

0 голосов
/ 17 апреля 2010

Может быть, глупый вопрос, но вы это где-то определяете? Ваше определение будет выглядеть примерно так:

bool MyClass::m_someVar = false;
...