Добрый день.
Имею внешнюю 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++?
" Руль " <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 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Здравствуйте, 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);
Если портятся локальные переменные, то скорее всего что-то не так с размером возвращаемого параметра. Попробуй исследовать возвращаемые значения как-то так
DWORD b = 0xcccccccc;
DWORD ret = 0xcccccccc;
(WORD&)ret = fn_Func2((BYTE*)&b);
и посмотри какие значения будут в ret и b после вызова.
COFF пишет:
> Если портятся локальные переменные, то скорее всего что-то не так с > размером возвращаемого параметра. Попробуй исследовать возвращаемые > значения как-то так > > DWORD b = 0xcccccccc; > DWORD ret = 0xcccccccc; > (WORD&)ret = fn_Func2((BYTE*)&b);
с соглашениями о связях когда не так что-то , тоже может портиться стек.
Здравствуйте, Руль, Вы писали:
Р>function Func1; stdcall; cdecl; external DLLPath name 'XXX'; Р>function Func2(var vOut:byte):WORD; stdcall; cdecl; external DLLPath name 'XXX';
Так stdcall или cdecl? Возможно, компилятор Дельфи, видя такое, не применяет ни одно из них. Попробуйте оставить только stdcall и в С++ тоже напишите __stdcall.