2013-03-16 2 views
0

я в процессе написания набор библиотек, где выступает в качестве основного компонента , позднее связывание других через плагин API. Теперь проблема заключается в следующем:Используя макрос, который получает доступ к глобальной переменной внутри плагин

В основной библиотеке содержится класс ведения журнала, а также набор макросов для облегченного ведения журнала.

/* File: Log.h */ 

namespace XYZ 
{ 
    class XYZ_API Log 
    { 
     /* Logfile and console output management */ 
    }; 

    // Global log object 
    extern XYZ_API Log logger; 

    // Macros using aforementioned variable 
    #ifndef XYZ_DISABLE_LOGGING 
     #define LOG_DEBUG(msg) /* statements using logger object */ 
     #define LOG_INFO(msg) /* etc. */ 
    #else 
     #define LOG_DEBUG(msg) 
     #define LOG_INFO(msg) 
    #endif 
} 

Определения переменного регистратора так просто, как он получает:

/* File: Log.cpp */ 

namespace XYZ 
{ 
    // Initialize the global log object 
    Log logger; 

    /* Log class implementation */ 
} 

Теперь, когда делает использование этих макросов из самих или от клиентского приложения основной библиотеки, все работает просто хорошо. Но как только я пытаюсь использовать их в одном из плагинов:

/* File: MyPlugin.cpp */ 

namespace XYZ 
{ 
    MyPlugin::MyPlugin(/* ... */) 
    { 
     LOG_INFO("This won't link!"); 
     logger. 
    } 
} 

Следующая ошибка линкера возникает (с использованием набора инструментов V110 MSVC):

LNK2001: unresolved external symbol "class XYZ::Log XYZ::logger" ([email protected]@@[email protected]@A) 

Это, как говорится, это самый символ, безусловно, является экспортируется из библиотеки плагинов (присутствует в файле .lib). Плагин также связан с основной библиотекой. Другие символы (классы и их методы) отлично работают.

Я понимаю, что для загрузки во время загрузки символов из загруженной DLL необходимо запросить GetProcAddress/dlsym (или какой-либо эквивалент). Кроме того, у меня есть интерфейс, который может через чисто виртуальный класс сделать любой объект из основной библиотеки, доступной для плагинов.

Сейчас для Актуальный вопрос: Есть ли способ сделать вышеуказанный план работы, или я должен воздерживаться от использования макросов регистрации в коде плагина?

Edit:

опций командной строке компилятора (библиотека ядра) являются (длинные имена путей раздели):

/GS /analyze- /W3 /Zc:wchar_t /I"[...]" /ZI /Gm /Od /Fd"[...]" /fp:precise /D "XYZ_EXPORT_SYMBOLS" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_USRDLL" /D "_WINDLL" /D "_UNICODE" /D "UNICODE" /errorReport:prompt /WX- /Zc:forScope /RTC1 /Gd /Oy- /MDd /Fa"[...]" /EHsc /nologo /Fo"[...]" /Fp"[...]" 

И для компоновщика:

/OUT:"[...]" /MANIFEST /NXCOMPAT /PDB:"[...]" /DYNAMICBASE "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "odbc32.lib" "odbccp32.lib" /IMPLIB:"[...]" /DEBUG /DLL /MACHINE:X86 /INCREMENTAL /PGD:"[...]" /SUBSYSTEM:WINDOWS /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /ManifestFile:"[...]" /ERRORREPORT:PROMPT /NOLOGO /TLBID:1 

Same вещь для библиотеки плагинов; в значительной степени точно такая же строка, за исключением путей:

/GS /analyze- /W3 /Zc:wchar_t /I"[...]" /ZI /Gm /Od /Fd"[...]" /fp:precise /D "XYZ_EXPORT_SYMBOLS" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_USRDLL" /D "_WINDLL" /D "_UNICODE" /D "UNICODE" /errorReport:prompt /WX- /Zc:forScope /RTC1 /Gd /Oy- /MDd /Fa"[...]" /EHsc /nologo /Fo"[...]" /Fp"[...]" 

И подключение плагинов; Опять же, в основном та же линия, за исключением ссылки на основную библиотеку:

/OUT:"[...]" /MANIFEST /NXCOMPAT /PDB:"[...]" /DYNAMICBASE "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "odbc32.lib" "odbccp32.lib" "[path to core lib]" /IMPLIB:"[...]" /DEBUG /DLL /MACHINE:X86 /INCREMENTAL /PGD:"[...]" /SUBSYSTEM:WINDOWS /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /ManifestFile:"[...]" /ERRORREPORT:PROMPT /NOLOGO /TLBID:1 

ответ

1

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

Предполагаю, что вы пишете для Windows, повторно: ошибка LNK2001. Поиск этой ошибки дает страницы помощи Microsoft. Вероятно, они должны помочь.

Было сказано, что вы устанавливаете флаги для компиляции и компоновщика?

+0

Спасибо за ваш ответ!Хорошо, я наткнулся на список Microsoft относительно причин LNK2001 ранее, но не смог связать какие-либо проблемы, перечисленные там, в моей ситуации. Тем не менее, я добавил свои параметры командной строки выше, надеюсь, что это поможет! – Zultar

+0

Я использовал эти проблемы при некорректном упорядочении библиотеки из памяти. Я не вижу, где вы ошибаетесь. Вы пытались явно указать «/ EXPORT: logger» или «/ EXPORT: XYZ :: logger» в сборке ядра lib, а также попробовать '/ FORCE' в плагине lib, чтобы узнать, помогает ли она преодолеть ошибку связывания. –

+0

Я такой толстый. Я случайно определил один и тот же макрос экспорта в обоих библиотечных компонентах. Из-за этого 'XYZ :: logger' был объявлен' dllexport' для плагина. Неудивительно, что это не сработало. В любом случае, спасибо, что указали мне в правильном направлении! :) – Zultar