2016-09-06 4 views
-1

Я работаю над компиляцией с Visual Studio 2015 большого количества файлов кода, написанных первоначально для использования в Linux, с использованием g ++. В частности, мне нужна DLL для использования с другой программой. К сожалению, я столкнулся с рядом проблем.Ссылка на dll компилируется, но вызывает segfault

После выполнения некоторых исследований я попытался добавить __declspec (dllexport) в файлы заголовков. Это помогло с некоторыми ошибками компиляции, но не работало для статических функций-членов и переменных. Затем я создал файл .def, который избавился от оставшихся ошибок в компиляции, но после запуска некоторых тестов, скомпилированных в одно и то же время (и с одним и тем же компилятором), многие из них потерпели неудачу из-за segfaults. Те же тесты успешны, если я создаю его как .lib или свяжу тесты непосредственно с различными объектными файлами, но для последней программы мне нужен DLL. (Исходная сборка с использованием g ++ создает .so). Я не смог найти кого-нибудь еще с проблемой, подобной этому.

Вот упрощенная версия часть кода, который я нашел, чтобы иметь отношение к одной из линий, которые будут вызывать Segfault:

В библиотеке, заголовок:

class FirstClass 
{ 
public: 
    static const char *FIRST_CLASS_NAME; 
} 

и файл CPP:

const char *FirstClass::FIRST_CLASS_NAME = "FIRST_CLASS"; 

Все в тестовый файл, который ссылается эта переменная будет вызывать Segfault с .dll. В частности, если у меня есть строка

std::cout << FirstClass::FIRST_CLASS_NAME << std::endl; 

затем, если связан с .dll будет Segfault, но если связано с .lib, он будет выводить

FIRST_CLASS 

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

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

+0

[This] (http: // stackoverflow.com/a/19374253/3344612) ответ должен дать вам несколько советов – teivaz

+0

Я не эксперт по файловым файлам, но у меня был большой успех в свое время только с семантикой __declspec dllimport/dllexport, упомянутой в приведенной выше ссылке. Мне любопытно, какие у вас проблемы с __declspec (dllexport)? –

+0

Я предлагаю, чтобы не dllexport статический член. dllexport вместо функции. Инкапсулируйте статический элемент с помощью функции. – neohope

ответ

0

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

Вы должны использовать dllexport и dllimport в качестве пары. dllexport, где вы определяете их в общей библиотеке (dll) и dllimport, где вы используете их в приложении. Обычно у вас есть макрос, который вычисляет либо __declspec (dllexport), либо __declspec (dllimport) в зависимости от того, где он используется. Например.

#ifdef _DLL  // inside the DLL 
    #define DLLExportImport __declspec(dllexport) 
#else   // outside the DLL 
    #define DLLExportImport __declspec(dllimport) 
#endif 

И использовать его там, где вы определяете класс:

class DLLExportImport FirstClass 
{ ... }; 

Определение символа _DLL по мере необходимости в соответствующих проектах. Visual Studio предопределяет _DLL при создании нового проекта dll.

В настоящее время файлы .def не подходят в большинстве случаев.

+0

Я не понял, как использовать эти макросы. Тесты успешны, когда я правильно использую __declspec. Спасибо всем. – ejwilson

Смежные вопросы