Страница: 1 |
Страница: 1 |
Вопрос: Передача параметра типа char в dll
Добавлено: 05.02.06 04:54
Автор вопроса: Brusco | ICQ: 175617069
Скомпилил я значит dll'ку, создал lib-файл. В ней функция объявлена так:
extern "C" _declspec(dllexport) RGBImageRec __stdcall DIBImageLoad(LPCSTR Filename)
Создал проект exe-файла, передаю параметр в библиотеку:
DIBImageLoad("c:\\1.bmp");
В заголовочном файле функция объявлена как:
RGBImageRec * APIENTRY DIBImageLoad(LPCSTR Filename);
И не работает из C++ проекта - dll'ка принимает какую-то муть вместо указателя на строку и вылетает. А вот в VB всё нормально.
Это такая особенность передачи параметров в C++ или глюки с указателями на char?
Ответы
Всего ответов: 8
Номер ответа: 1
Автор ответа:
GSerg
Вопросов: 0
Ответов: 1876
Профиль | | #1
Добавлено: 05.02.06 06:50
RGBImageRec и RGBImageRec* - разные вещи (это раз)...
Где \n - это два...
Номер ответа: 2
Автор ответа:
HOOLIGAN
Вопросов: 0
Ответов: 1066
Профиль | | #2
Добавлено: 05.02.06 11:29
Если правильно понял, RGBImageRec - это структура.
Ф-ция DIBImageLoad не может вернуть структуру. Только указатель на неё. Например так:
typedef struct RGBImageRec{
int ImageSize; //тут какие-нибудь поля структуры
LPVOID lpData;
}RGBImageRec;
RGBImageRec MyImage;
//===============================================================
extern "C" _declspec(dllexport) RGBImageRec * __stdcall DIBImageLoad(LPCSTR Filename)
{
RGBImageRec* lpImage=&MyImage;
MessageBox( 0, Filename, NULL, NULL );
lpImage->ImageSize = 1;
lpImage->lpData = (LPVOID)2;
return lpImage;
}
и можешь вызывать свой DIBImageLoad("c:\\1.bmp"
Номер ответа: 3
Автор ответа:
Brusco
ICQ: 175617069
Вопросов: 4
Ответов: 24
Профиль | | #3
Добавлено: 06.02.06 03:53
Спасибо, всё работает. Но у меня возникло несколько вопросов)
Почему эта переменная MyImage обязательно должна быть глобальной?
В exe я переменную типа объявляю, а потом вызываю функцию:
RGBImageRec *texture1;
texture1 = DIBImageLoad("c:\\1.bmp"
Так если я зарегю другую типа *texture2, и вызову функцию по новой, то в texture1 останется старая текстура или затрётся новой? Там же всё таки адрес передаётся...
Номер ответа: 4
Автор ответа:
HOOLIGAN
Вопросов: 0
Ответов: 1066
Профиль | | #4
Добавлено: 06.02.06 13:41
Переменная не обязательно должна быть глобальная. Она может быть и локальной внутри процедуры.
Вообще это только пример был с глобальной переменной внутри dll.
Обычно делается иначе: ехе выделяет память под переменную и передает указатель на переменную для заполнения в dll. Например так: две переменные, обе заполняются в dll, и содержат каждая свои данные:
int ImageSize;
LPVOID lpData;
char ImageFile[256];
}RGBImageRec;
//=================================================================
extern "C" _declspec(dllexport) int __stdcall DIBImageLoad( LPVOID lpVar, LPCSTR Filename)
{
RGBImageRec * tempImage;
tempImage = (RGBImageRec *)lpVar; //адрес переменной из ехе
tempImage->ImageSize = strlen (Filename); //заполнение ехе-шной переменной
tempImage->lpData = (LPVOID)2;
strcpy (tempImage->ImageFile, Filename);
return 1;
}
/////////////////////////////
// Это в ехе
/////////////////////////////
typedef struct RGBImageRec{
int ImageSize;
LPVOID lpData;
char ImageFile[256];
}RGBImageRec;
//=================================================================
RGBImageRec var_1, var_2;
 IBImageLoad (&var_1, "c:\\123.bmp"
 IBImageLoad (&var_2, "c:\\987654.bmp"
wsprintf (buffer,
"var_1.ImageSize = %d\nvar_1.lpData = %d\nvar_1.ImageFile : %s",
var_1.ImageSize, var_1.lpData, var_1.ImageFile );
MessageBox (NULL, buffer, caption, MB_OK);
wsprintf (buffer,
"var_2.ImageSize = %d\nvar_2.lpData = %d\nvar_2.ImageFile : %s",
var_2.ImageSize, var_2.lpData, var_2.ImageFile );
MessageBox (NULL, buffer, caption, MB_OK);
Номер ответа: 5
Автор ответа:
Brusco
ICQ: 175617069
Вопросов: 4
Ответов: 24
Профиль | | #5
Добавлено: 07.02.06 02:40
Понятно, спасибо!
Я ещё попробовал другую функция сделать, только без указателей, в VB опять нормально - принимает значение, а в C++ возвращается не то:
err = (UINT)GetError;
Пришлось приведение использовать, потому-что компилятор выдавал несоответсвие типов.
В dll:
{
return ErrorCode;
}
Номер ответа: 6
Автор ответа:
GSerg
Вопросов: 0
Ответов: 1876
Профиль | | #6
Добавлено: 07.02.06 05:14
Brusco, может азы C++ изучить перед писанием на нём?
Ну помещаешь ты в err адрес функции GetError. Ну и толку тебе от этого адреса?
Пока скобки не поставишь, функция не будет вызвана.
err = GetError();
Номер ответа: 7
Автор ответа:
Brusco
ICQ: 175617069
Вопросов: 4
Ответов: 24
Профиль | | #7
Добавлено: 08.02.06 02:10
Ну азы и внимательность не совсем одно и тоже)
Скопировал из VB код, а не посмотрел, да и компилятор ошибок не выдаёт.
Буду внимательней в следующий раз.
Номер ответа: 8
Автор ответа:
GSerg
Вопросов: 0
Ответов: 1876
Профиль | | #8
Добавлено: 08.02.06 06:40
Компилятор как раз выдаёт. Только ты своим (UINT) его игнорируешь...