Используйте функцию из c ++ DLL - PullRequest
0 голосов
/ 08 июля 2019

Я использую QT, и это QLibrary, чтобы использовать DLL. Но я не могу загрузить функцию внутри нее и использовать ее в своем проекте.

void Compose3wnThread::GenPrinterFile()
{
    lib_3wn = new QLibrary;
    lib_3wn->setFileName(qApp->applicationDirPath() + "/" + MyDLL);
    lib_3wn->load();

    if (lib->isLoaded())
    {
        typedef int (*initial)(char*, int, char*);
        initial function = (initial)lib_3wn->resolve("API_Initial");

        int result;
        result = 0;
        //result = (int)function("Nobel Superfine", 12, "D:\\final.3wn");

    }
}

lib_3wn - это объект QLibrary, в котором хранится моя DLL. И после выполнения приведенного выше кода функция остается 0x0 или не имеет никакого значения. Это функция, которую мне нужно загрузить из DLL.

int API_Initial(char *machineType, int totalLayers, char *fileName)

Эта функция взята из документа, который определяет функции внутри используемой библиотеки DLL. Я не создавал DLL сам.

Как мне это исправить?

Ответы [ 3 ]

1 голос
/ 08 июля 2019

Из документации QLibrary :

Символ должен быть экспортирован как функция C из библиотеки.Это означает, что функция должна быть заключена в extern "C", если библиотека скомпилирована с помощью компилятора C ++.В Windows вы также должны явно экспортировать функцию из DLL, используя директиву компилятора __declspec(dllexport)

. Вы должны добавить extern "C" к объявлению и определению API_Initial:

extern "C" int API_Initial(char *machineType, int totalLayers, char *fileName)

или заключите его в блок extern "C":

extern "C" {
    int API_Initial(char *machineType, int totalLayers, char *fileName);
}

C ++ имеет перегрузку функций, но для каждой функции требуется уникальное имя для использования компоновщиком.Для этого имена искалечены для кодирования их подписи.Это означает, что int foo(int) и int foo(double) имеют разные имена, и компоновщик может их различать, но ни один из них не называется foo.Одна называется ?foo@@YAHH@Z, а другая - ?foo@@YAHN@Z (в Windows. Другие платформы имеют разные схемы искажения имен, но идея та же).

Это означает, что когда QLibrary ищетимя API_Initial это не может найти это.Он может найти имя ?API_Initial@@YAHPEADH0@Z, но нет хорошего независимого от платформы способа получить это имя.

Добавление extern "C" в объявление функции отключает искажение этого имени, но исключает функциюперегрузка, ограничивает имя глобальным пространством имен и ограничивает интерфейс функции только тривиально копируемыми типами объектов и указателями.

0 голосов
/ 08 июля 2019

Спасибо за все ответы.Я вроде исправил это, используя комментарий @Antonio Dias.Я использовал Dependency Walker , а затем увидел, что упомянутая мной DLL зависит (не подразумевается) от двух [2] других файлов DLL.

Предыдущий код уже правильный.

0 голосов
/ 08 июля 2019

Попробуйте

initial function = (initial)lib_3wn->resolve("_API_Initial");

или

initial function = (initial)lib_3wn->resolve("_API_Initial@4");

или

initial function = (initial)lib_3wn->resolve("@API_Initial@4");

в зависимости от соглашения о вызовах. См. это для получения дополнительной информации

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...