Российский производитель и разработчик сертифицированного измерительного оборудования с 1987 года


Динамическая загрузка lusbapi

Вы не вошли.

 Поиск | Регистрация | Вход 

Oleg
11.05.2010 10:42:55
#1

Гость

Динамическая загрузка lusbapi

Здравствуйте, немогу разобратся как динамически загрузить библиотеку
пишу так:
ILE440 *pE440;
typedef LPVOID (WINAPI *PFN_MyFunction)(CHAR *);
PFN_MyFunction CreateLInstance1;
HINSTANCE hMyDll;
hMyDll=::LoadLibrary("Lusbapi");

CreateLInstance1=(PFN_MyFunction)GetProcAddress(hMyDll,"CreateLInstance");//при проверки не выдает ноль еслиб адрес функции небыл бы получен
string a="e440";
pE440 = static_cast<ILE440 *>(CreateLInstance1((PCHAR)*a.c_str()));//здесь возникает ошибка

11.05.2010 11:08:45
#2

Сотрудник "Л Кард"
Здесь с 18.04.2014
Сообщений: 810

Re: Динамическая загрузка lusbapi

А что это с преобразованием типов в последней строке?
c_str() возвращает const char*, дальше зачем-то берется первый символ строки (оператор *) и преобразуется в PCHAR.
Как насчет CreateLInstance(a.c_str())?
Чтобы убрать const, либо объявите PFN_MyFunction)(const CHAR *), либо можно CreateLInstance(const_cast<PCHAR>(a.c_str()))

Oleg
11.05.2010 11:31:09
#3

Гость

Re: Динамическая загрузка lusbapi

Перепробывал все предложеные варианты суть ошибки не поменялась ,Access violation at adres 00000. Read adres 0000

11.05.2010 12:58:34
#4

Сотрудник "Л Кард"
Здесь с 18.04.2014
Сообщений: 810

Re: Динамическая загрузка lusbapi

Вообще не совсем ясно, зачем тут std::string и c_str() - почему не CreateLInstance1("e440")?

Выведите для проверки:
результат LoadLibrary()
результат GetProcAddress()
аргумент CreateLInstance(), сохраненный во временной переменной. Вот исходник, который я только что собрал GCC:

#include <string>
#include "Lusbapi.h"
main()
{
ILE440 *pE440;
typedef LPVOID (WINAPI *PFN_MyFunction)(CHAR *);
PFN_MyFunction CreateLInstance1;
HINSTANCE hMyDll;
hMyDll=::LoadLibrary("Lusbapi");
CreateLInstance1=(PFN_MyFunction)GetProcAddress(hMyDll,"CreateLInstance");
std::string a="e440";
PCHAR pc = const_cast<PCHAR>(a.c_str());
printf("library %p, proc %p, arg %p//n", hMyDll, CreateLInstance1, pc);
pE440 = static_cast<ILE440 *>(CreateLInstance1(pc));
printf("pE440 %p//n", pE440);
}

Выдало без ошибок
library 00450000, proc 004511B4, arg 003F3FDC
pE440 008E2BC8
(числа будут зависеть от компилятора, конечно)

Oleg
11.05.2010 13:33:19
#5

Гость

Re: Динамическая загрузка lusbapi

Получается  что был неверно передан параметр ?
PCHAR pc = const_cast<PCHAR>(a.c_str()); такое преобразование  дало правильный вызов ? спасибо за пояснения  на gcc 4.4  с исправлениями  все собралось

11.05.2010 16:44:55
#6

Сотрудник "Л Кард"
Здесь с 18.04.2014
Сообщений: 810

Re: Динамическая загрузка lusbapi

В Вашем исходном варианте (PCHAR)*a.c_str() ошибка, потому что это есть приведение к типу PCHAR значения (*a.c_str()), т.е. не указателя, а самого символа. Если строка a содержит "e440", то (*a.c_str()) == //'e//', (PCHAR) от него дает некорректный указатель 0x00000065 (ASCII код //'e//').

Годилось бы (PCHAR)a.c_str() (без звездочки) или (CHAR*)a.c_str().
Но раз уж мы пишем на C++, резонно будет применить не C-style преобразование типов, а правильный_cast<тип>(выражение), в данном случае static_cast или лучше всего const_cast. Он как раз придуман, чтобы не дать сделать неправильное преобразование, т.к. разрешает только убирать const, но не менять тип существенно.

PCHAR pc = const_cast<PCHAR>(*a.c_str());
error: invalid const_cast from type char to type CHAR*

PCHAR pc = static_cast<PCHAR>(*a.c_str());
error: invalid static_cast from type const char to type CHAR*

http://www.intuit.ru/department/pl/cpp/13/2.html

Временная переменная (pc) не нужна, это я ввел для наглядности.

Oleg
19.05.2010 10:16:58
#7

Гость

Re: Динамическая загрузка lusbapi

Здавствуте  решил не создавать велосипед взял клас из вашего примера динамической загрузки
но компилятор gcc 4.4   ругается на
LPVOID WINAPI TLoadDll::CallCreateLInstance(void)
{
    if(hDll == NULL) return NULL;
    return FARPROC(::GetProcAddress(hDll, "CreateLInstance"));
} с тем что в функции обья вленой как войд возвращается адрес.

20.05.2010 12:33:56
#8

Сотрудник "Л Кард"
Здесь с 18.04.2014
Сообщений: 810

Re: Динамическая загрузка lusbapi

Точнее, с тем, что FARPROC, который есть typedef (int (*FARPROC)(), то есть указатель на int proc(void), преобразуется оператором return к LPVOID:

invalid conversion from int (*)() to void*

Очевидно, под msvc собирается, а gcc строг и такого не потерпит (и правильно, честно говоря).

Лучше поставить правильные типы возвращаемого значения прямо в класс.

pCreateInstance WINAPI TLoadDll::CallCreateLInstance(void)
{
if (hDll == NULL) return NULL;
return pCreateInstance(::GetProcAddress(hDll, "CreateLInstance"));
}
pGetDllVersion WINAPI TLoadDll::CallGetDllVersion(void)
{
if (hDll == NULL) return NULL;
return pGetDllVersion(::GetProcAddress(hDll, "GetDllVersion"));
}

Либо return LPVOID(...), но это хуже.