Как вы строите заменяемые библиотеки DLL с Visual Studio? - PullRequest
3 голосов
/ 11 декабря 2011

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

Я где-то читал, что каждая новая версия DLL должна быть "двоично-совместимой" со старой. По умолчанию совместимы ли библиотеки DLL с двоичным файлом Visual Studio, если я не изменяю имена функций?

Ответы [ 3 ]

2 голосов
/ 11 декабря 2011

Вы должны сделать больше, чем просто сохранить имена функций одинаковыми. То, что вы должны гарантировать, называется совместимостью прикладного двоичного интерфейса, или ABI.

Есть много вещей, которые влекут за собой только имена символов. Например, у вас есть такие вещи, как сохранение структур данных, которые передаются через границу DLL, одинакового размера, и компилятор должен размещать все члены класса, определенные в вашем модуле, но доступ к которым осуществляется вне его, в том же относительном месте. Многое зависит от ABI компилятора. Компиляторы Microsoft имеют плохую привычку не быть ABI-совместимыми между версиями, в то время как некоторые другие компиляторы работают немного сложнее, чтобы быть совместимыми. Но помните, что это требует больше, чем просто использование одного и того же компилятора.

Вероятно, вам нужно будет прочитать о том, как поддерживать совместимость с ABI в вашей среде, поскольку, вероятно, в нем содержится больше деталей, чем можно было бы перечислить здесь, и существует множество способов ошибиться. Вот одна короткая статья . Могут быть и лучшие, особенно для компиляторов MSVC.

1 голос
/ 11 декабря 2011

Один из способов сделать это - перекомпилировать библиотеки DLL.Библиотеки совместимы при условии, что версия компилятора (Visual Studio) не изменяется.В противном случае вам придется проверить руководство на совместимость между версиями Visual Studio.

Другой способ сделать это - динамически загрузить dll с помощью функции LoadLibrary , а затем с помощью GetProcAddress.функция для получения адреса функции, которую вы хотите вызвать.

Если вы используете последний, вы можете использовать любой компилятор, если вы правильно экспортируете функции с помощью dllexport и импортируете их с помощью dllimport.Подробнее здесь .

1 голос
/ 11 декабря 2011

Если вы экспортируете классы из вашей DLL, вы нарушите совместимость, если вы измените версию компилятора.Чтобы решить эту проблему, сделайте это.

Создайте интерфейсы классов, такие как:

class EXPORT_IMPORT_MACROS IMyApi{
public:
 virtual void doSomething( IOtherApi* api ) = 0;
 virtual void doSomething2( IOtherApi2* api ) = 0;
};

и экспортируйте их из своей библиотеки DLL.Он даст вам заголовочные файлы, которые не зависят от реализации DLL, а также могут быть экспортированы, что означает, что он не будет создавать никаких проблем с различными версиями библиотеки времени выполнения.Также вы можете взглянуть на технологию COM.

...