Явная загрузка DLL - PullRequest
       18

Явная загрузка DLL

3 голосов
/ 10 августа 2009

Я пытаюсь явно связать с DLL. Нет других доступных ресурсов, кроме самого файла DLL и некоторой документации о классах и их функциях-членах.

Из документации каждый класс поставляется со своим

  1. член typedef
    пример: typedef std::map<std::string,std::string> Server::KeyValueMap, typedef std::vector<std::string> Server::String Array
  2. перечисление члена
    пример: enum Server::Role {NONE,HIGH,LOW}
  3. функция-член
    пример: void Server::connect(const StringArray,const KeyValueMap), void Server::disconnect()

Реализуя коды из поиска Google, мне удается загрузить DLL может вызвать функцию отключения ..

дир.ч

LPCSTR disconnect = "_Java_mas_com_oa_rollings_as_apiJNI_Server_1disconnect@20";  
LPCSTR connect =   
"_Java_mas_com_oa_rollings_as_apiJNI_Server_1connect@20";

Я получил имя функции выше от зависит от.exe. Это то, что называется в C ++ именами украшенных / искаженных функций?

main.cpp

#include <iostream>
#include <windows.h>
#include <tchar.h>
#include "dir.h"

typedef void (*pdisconnect)();

int main()
{
    HMODULE DLL = LoadLibrary(_T("server.dll"));  
    pdisconnect _pdisconnect;`

    if(DLL)
    {
        std::cout<< "DLL loaded!" << std::endl;
        _disconnect = (pdisconnect)GetProcAddress(DLL,disconnect);


        if(_disconnect)
        {
            std::cout   << "Successful link to function in DLL!" << std::endl;
        }

        else
        {
            std::cout<< "Unable to link to function in DLL!" << std::endl;
        }
    }  
    else    
{  
std::cout<< "DLL failed to load!" << std::endl;  
}  
FreeLibrary (DLL);  
return 0;}

Как мне вызвать (например) функцию connect , которая имеет тип данных параметра, объявленный в самой dll?

Редактировать

больше информации:

  • DLL поставляется с примером реализации с использованием Java. Пример Java содержит оболочку Java, созданную с использованием SWIG, и исходный код.
  • В документации перечислены все классы, их функции-члены, а также их типы данных. Согласно документу, список был сгенерирован из исходных кодов C ++. (??)
  • Никакой другой информации не было предоставлено (никакой информации о том, какой компилятор использовался для генерации DLL)

Мой коллега реализует интерфейс с использованием Java на основе приведенного примера Java, в то время как меня попросили реализовать с использованием C ++. DLL от сторонней компании.

Я спрошу их о компиляторе. Любая другая информация, которую я должен получить от них?

Я быстро прочитал о JNI, но я не понимаю, как это реализовано в этом случае.

Update

Я немного смущен ... (хорошо, хорошо ... очень смущен)

  1. Вызываю ли я (GetProcAddress) каждую публичную функцию-член отдельно, только когда я хочу их использовать?
  2. Создать ли фиктивный класс, который имитирует класс в dll. Затем внутри определения класса я вызываю эквивалентную функцию из DLL? (Имею ли я здесь смысл?) Fnieto, это то, что вы показываете мне в конце своего поста?
  3. Можно ли создать экземпляр всего класса из DLL?

Я пытался использовать функцию подключения, описанную в моем первом посте. Из вывода DLL-файла Depends.exe

  • std :: map // KeyValueMap имеет следующие функции-члены: del, empty, get, has_1key, set
  • std :: vector // StringArray имеет следующие функции-члены: добавить, емкость, очистить, получить, isEMPTY, резерв, установить, размер

, который отличается от функций-членов map и vector в моем компиляторе (VS 2005) ...

Есть идеи? или я здесь получаю неправильную картину ...

Ответы [ 3 ]

3 голосов
/ 10 августа 2009

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

0 голосов
/ 04 июня 2016

Для связи с DLL вам необходимо:

  1. библиотека импорта (файл .LIB), в которой описывается связь между именами C / C ++ и экспортом DLL.
  2. сигнатуры C / C ++ экспортируемых элементов (обычно функций), описывающие соглашение о вызовах, аргументы и возвращаемое значение. Обычно это происходит в заголовочном файле (.H).

Судя по вашему вопросу, вы можете угадать сигнатуры (# 2), но вам действительно нужен файл LIB (# 1).

Компоновщик может помочь вам сгенерировать LIB из DLL, используя промежуточный DEF. Обратитесь к этому вопросу для получения более подробной информации: Как создать библиотеку импорта из DLL?

Затем вам нужно передать .lib в качестве «дополнительной библиотеки» компоновщику. DLL должна быть доступна в PATH или в целевой папке.

0 голосов
/ 10 августа 2009

Я был бы очень осторожен, если бы вы были вами: библиотека STL не была разработана для использования за такими границами компиляции.

Не то чтобы это нельзя было сделать, но вам нужно знать, во что вы ввязываетесь.

Это означает, что использование классов STL через границы DLL может безопасно работать только в том случае, если вы компилируете свой EXE с тем же точным компилятором и версией, и теми же настройками (особенно DEBUG vs. RELEASE), что и исходная DLL. И я имею в виду "точное" совпадение.

Стандартная библиотека STL C ++ - это спецификация поведения, а не реализации. Разные компиляторы и даже разные ревизии одного и того же компилятора могут и будут различаться в зависимости от реализации кода и данных. Когда ваша библиотека возвращает вам std::map, она возвращает вам биты, которые работают с версией DLL STL, а не обязательно кодом STL, скомпилированным в вашем EXE.

(и я даже не касаюсь того факта, что искажение имен также может отличаться от компилятора к компилятору)

Без подробностей о ваших обстоятельствах я не могу быть уверен; но это может быть червячная банка.

...