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

Я пытаюсь явно связать с 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 может вызвать функцию отключения.

dir.h

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, но я не понимаю, как это реализовано в этом случае.

Обновить

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

  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 ответа

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

Для того, чтобы связать с DLL, вам необходимо:

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

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

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

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

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

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

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

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

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

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

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