Visual Basic, .NET, ASP, VBScript
 

   
   
     

Форум - Общий форум

Страница: 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, и содержат каждая свои данные:

typedef struct RGBImageRec{
    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;
    
    ;DIBImageLoad (&var_1, "c:\\123.bmp";);
    ;DIBImageLoad (&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++ возвращается не то:

UINT APIENTRY GetError(void);


UINT err;
err = (UINT)GetError;


Пришлось приведение использовать, потому-что компилятор выдавал несоответсвие типов.

В dll:
extern "C" _declspec(dllexport) UINT __stdcall GetError(void)
{
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) его игнорируешь...

Ответить

Страница: 1 |

Поиск по форуму



© Copyright 2002-2011 VBNet.RU | Пишите нам