Динамический импорт класса C++ из DLL

Как правильно импортировать класс C++ из библиотеки DLL? Мы используем Visual C++.

Есть тройка dllexport / exports.def + LoadLibrary + GetProcAddress, но она не работает с классами C++, а работает только с функциями C. Это связано с изменением имен C++? Как мне заставить это работать?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
15
0
26 667
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

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

Вот практический пример, экспорт документа / представления MFC из библиотеки DLL, динамически загружаемый

dllexport / dllimport работает, поместите его перед именем класса в файле заголовка, и все готово.

Обычно вы хотите использовать dllexport в dll и dllimport в exe (но вы можете просто использовать dllexport везде, и он работает, если сделать это «правильно», он будет загружаться немного быстрее).

Очевидно, это для компиляции во время компоновки. Вы можете использовать директиву компоновщика / delayload, чтобы сделать его «динамическим», но, вероятно, это не то, что вы хотите от темы.

Если вам действительно нужна загрузка в стиле LoadLibrary, вам придется обернуть свои функции C++ оболочками "extern C". Проблема в том, что из-за искажения имени вы можете ввести полностью искаженное имя, и оно сработает.

Как правило, обходные пути заключаются в предоставлении функции C, которая возвращает указатель на правильный класс - COM работает таким образом, поскольку он экспортирует 4 функции C из dll, которые используются для получения методов интерфейса внутри объекта в dll.

Вам необходимо добавить следующее:

extern "C"
{
...
}

чтобы избежать искажения функций.

вы можете подумать о написании двух простых функций C:

SomeClass* CreateObjectInstace()
{
    return new SomeClass();
}

void ReleaseObject(SomeClass* someClass)
{
   delete someClass;
}

Используя только эти функции, вы можете впоследствии добавить / изменить функциональность создания / удаления вашего объекта. Иногда это называют фабрикой.

Разве эти имена SomeClass не должны иметь звездочки (т.е. быть указателями на SomeClass)?

Eli Bendersky 13.09.2011 18:17
Ответ принят как подходящий

Нашел решение на http://www.codeproject.com/KB/DLL/XDllPt4.aspx

Спасибо за ваши старания, парни и девушки

Проверьте этот вопрос. В принципе, есть два пути. Вы можете пометить класс с помощью _dllexport, а затем связать его с библиотекой импорта, и DLL будет загружена автоматически. Или, если вы хотите динамически загружать DLL, вы можете использовать идею фабричной функции, предложенную @titanae.

Другие вопросы по теме