Вызов внешней DLL из VC++ 6.0
От: Руль Россия www.guseynov.ru/resume.htm
Дата: 27.03.09 16:01
Оценка:
Добрый день.
Имею внешнюю DLL. Имею _работающий_ пример ее использования на Delphi.

function Func1; stdcall; cdecl; external DLLPath name 'XXX';
function Func2(var vOut:byte):WORD; stdcall; cdecl; external DLLPath name 'XXX';

переписал на VC++ в виде:

typedef WORD (WINAPI *typefn_Func1)();
typedef WORD (WINAPI *typefn_Func2)(byte * vOut);

Сделал красивый класс-обертку, корректно исполняю LoadLibrary и все такое прочее.

Вызов Func1, который без параметров проходит "на ура".
При вызове Func2 портятся мои внутренние локальные переменные.
Подозреваю, что из-за неправильного описания.
Вместо WINAPI, которое суть есть __stdcall, пробовал поставить как __cdecl, так и __fastcall.
При __fastcall все вылетало на exception, __cdecl тоже отрабатывал не нормально.

Подскажите, пожалуйста, как мне оформить вызов Func2 в C++?
Re: Вызов внешней DLL из VC++ 6.0
От: Sergey Россия  
Дата: 27.03.09 16:26
Оценка:
" Руль " <65592@users.rsdn.ru> wrote in message news:3344882@news.rsdn.ru...
> Добрый день.
> Имею внешнюю DLL. Имею _работающий_ пример ее использования на Delphi.
>
> function Func1; stdcall; cdecl; external DLLPath name 'XXX';
> function Func2(var vOut:byte):WORD; stdcall; cdecl; external DLLPath name 'XXX';
>
> переписал на VC++ в виде:
>
> typedef WORD (WINAPI *typefn_Func1)();
> typedef WORD (WINAPI *typefn_Func2)(byte * vOut);
>
> Сделал красивый класс-обертку, корректно исполняю LoadLibrary и все такое прочее.
>
> Вызов Func1, который без параметров проходит "на ура".
> При вызове Func2 портятся мои внутренние локальные переменные.
> Подозреваю, что из-за неправильного описания.
> Вместо WINAPI, которое суть есть __stdcall, пробовал поставить как __cdecl, так и __fastcall.
> При __fastcall все вылетало на exception, __cdecl тоже отрабатывал не нормально.
>
> Подскажите, пожалуйста, как мне оформить вызов Func2 в C++?

А как выглядит вызывающий Func2 код? В смысле, буфер ей достаточного размера дается? Дело то может быть и не в соглашении о вызовах.
Posted via RSDN NNTP Server 2.1 beta
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re[2]: Вызов внешней DLL из VC++ 6.0
От: Руль Россия www.guseynov.ru/resume.htm
Дата: 27.03.09 16:36
Оценка:
Здравствуйте, Sergey, Вы писали:

S>А как выглядит вызывающий Func2 код? В смысле, буфер ей достаточного размера дается? Дело то может быть и не в соглашении о вызовах.


Я передаю ссылку на один байт. Так написано в документации + так работает пример на Delphi.
Пример кода:
    HMODULE        hDll;
    typefn_Func1    fn_Func1;
    typefn_Func2    fn_Func2;

    hDll = ::LoadLibrary("XXX.dll");
    if (!hDll) return FALSE;

    fn_Func1 = (typefn_Func1)::GetProcAddress(hDll, "Func1");
    if(!fn_Func1) return FALSE;

    fn_Func2 = (typefn_Func2)::GetProcAddress(hDll, "Func2");
    if(!fn_Func2) return FALSE;

    WORD ret; // По документации функция должна вернуть при успехе 0
    ret = fn_Func1(); // все отлично, возвращается 0

    byte b;
    ret = fn_Func2(&b); // все плохо, возвращается не 0 и портятся мои переменные

    ::FreeLibrary(hDll);
Re[3]: Вызов внешней DLL из VC++ 6.0
От: COFF  
Дата: 27.03.09 21:46
Оценка:
Здравствуйте, Руль, Вы писали:

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

DWORD b = 0xcccccccc;
DWORD ret = 0xcccccccc;
(WORD&)ret = fn_Func2((BYTE*)&b);


и посмотри какие значения будут в ret и b после вызова.
Re[4]: Вызов внешней DLL из VC++ 6.0
От: MasterZiv СССР  
Дата: 28.03.09 11:09
Оценка:
COFF пишет:

> Если портятся локальные переменные, то скорее всего что-то не так с

> размером возвращаемого параметра. Попробуй исследовать возвращаемые
> значения как-то так
>
> DWORD b = 0xcccccccc;
> DWORD ret = 0xcccccccc;
> (WORD&)ret = fn_Func2((BYTE*)&b);

с соглашениями о связях когда не так что-то , тоже может портиться стек.
Posted via RSDN NNTP Server 2.1 beta
Re: Вызов внешней DLL из VC++ 6.0
От: dmitry_npi Россия  
Дата: 29.03.09 09:06
Оценка:
Здравствуйте, Руль, Вы писали:

Р>function Func1; stdcall; cdecl; external DLLPath name 'XXX';

Р>function Func2(var vOut:byte):WORD; stdcall; cdecl; external DLLPath name 'XXX';


Так stdcall или cdecl? Возможно, компилятор Дельфи, видя такое, не применяет ни одно из них. Попробуйте оставить только stdcall и в С++ тоже напишите __stdcall.
Атмосферная музыка — www.aventuel.net
Re[2]: Вызов внешней DLL из VC++ 6.0
От: Руль Россия www.guseynov.ru/resume.htm
Дата: 30.03.09 10:04
Оценка:
Перепробовал все варианты. В результате заработало со стандартным WINAPI, когда переделал описание с
typedef WORD (WINAPI *typefn_Func2)(byte* vOut);

на
typedef WORD (WINAPI *typefn_Func2)(byte& vOut);


и вызовы, соответственно с
ret = fn_Func2(&b); // все плохо, возвращается не 0 и портятся мои переменные

на
ret = fn_Func2(b); // все плохо, возвращается не 0 и портятся мои переменные


Чего-то я совсем не понял... описание переменных, передаваемых по ссылке как * и как & ведут себя со стеком по разному!?..
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.