В процедурах объявленных как extern "C" отказываются работать WinApi функции. Падают все, даже такие как MessageBox. Среда разработки dev c++ вот пример роцедуры extern "C" __stdcall __declspec(dllexport) void LoadSnar (int NumMonstr, int TypeSnar, char* &p_NameSnar) { MessageBox(NULL, "", "", MB_OK); if(TypeSnar == 0xFF) { p_NameSnar = (char*)((int)TStructOfMem.p_ShellDefs + (NumMonstr - i_ExistingMonstr +2)*32); return; } p_NameSnar = NameSnaryad[TypeSnar]; } Любая АПИ в этой процедуре падает. А если убрать extern "C" то искожается имя процедуры и сторонние приложения не могут вызвать процедуру по имени. Подскажите что делать?
Код (Text): .text:641413B2 LoadSnar@12 proc near ; CODE XREF: sub_64142390+Ap .text:641413B2 .text:641413B2 var_18 = dword ptr -18h .text:641413B2 var_14 = dword ptr -14h .text:641413B2 var_10 = dword ptr -10h .text:641413B2 var_C = dword ptr -0Ch .text:641413B2 arg_0 = dword ptr 8 .text:641413B2 arg_4 = dword ptr 0Ch .text:641413B2 arg_8 = dword ptr 10h .text:641413B2 .text:641413B2 push ebp .text:641413B3 mov ebp, esp .text:641413B5 sub esp, 18h .text:641413B8 mov [esp+18h+var_C], 0 .text:641413C0 mov [esp+18h+var_10], offset aErrorMonstrs ; "" .text:641413C8 mov [esp+18h+var_14], offset aCanTLoadingMon ; "" .text:641413D0 mov [esp+18h+var_18], 0 .text:641413D7 call MessageBoxA .text:641413DC sub esp, 10h .text:641413DF cmp [ebp+arg_4], 0FFh .text:641413E6 jnz short loc_64141406 .text:641413E8 mov ecx, [ebp+arg_8] .text:641413EB mov edx, dword_64143118 .text:641413F1 mov eax, [ebp+arg_0] .text:641
MessageBox отображается без заголовка почти в самом нижнем левом углу. А например FindFirstFile падает с ERROR_NOACCES
эх манглирование-мухлирование... Вызывайте по ординалу. или используйте def-файл: Код (Text): EXPORTS Имя_функции, которую манглить не надо
HiroProtagonist верно заметил. Dev С++ зачем-то чистит стек после вызова, но MessageBox уже почистил перед выходом. Одно слово - бесплатный компилятор!
AsmGuru62 >Dev С++ зачем-то чистит стек после вызова, но MessageBox уже почистил перед выходом. Непохоже. Скорее этот компилятор просто не любит пуши, и сразу после вызова MessageBox'а отменяет то, что эта апи почистила. Код (Text): .text:641413B5 sub esp, 18h .text:641413B8 mov [esp+18h+var_C], 0 .text:641413C0 mov [esp+18h+var_10], offset aErrorMonstrs ; "" .text:641413C8 mov [esp+18h+var_14], offset aCanTLoadingMon ; "" .text:641413D0 mov [esp+18h+var_18], 0 .text:641413D7 call MessageBoxA .text:641413DC sub esp, 10h <- sub, не add! Diakon Extern "C" в данном случае влияет только на манглирование имени функции. Падает не из-за этого.
Diakon Выложи бинарник который падает куда-нибудь. Желательно в минимальном варианте. Комилятор там GCC, и не надо писать ерунду про то что он плохой. Я на 200% уверен что ошибка в коде.
Проблема решилась. Я ставил хук в коде и прыгал в свою длл . Хук писал на масме и создавал объектный файл, который линковал с++. Так вот код в масме pusha pushf преобразовался почему-то в итоге в pushad pushfw !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Пришлось уточнять, что я имел в виду.
>pushf >pushfw Лол. Тоже как-то обожглись именно на этом. Ситуация осложнялась тем, что этот код выполнялся в r0, причём окружение было таково, что невозможна была ни отладка на VM, ни генерация крэшдампа (из-за других наших неверных решений). Таким образом несколько часов пытались понять причину остановов реальной мащины при запуске кода – до тех пор пока внимательно не изучили каждую инструкцию, собранную компилятором msvc из кода инлайн-ассемблера.
[offtop] И после этого мне будут доказывать, что at&t синтаксис, который приучает для всех команд писать постфиксы, указывающие размер операндов -- это зло. =) [/offtop]
В интеловском синтаксисе тоже никто суффиксы ставить не запрещает - но не ставят же. А в AT&T напрягают проценты дурацкие перед каждым именем регистра и обратный (непривычный) порядок аргументов.
cppasm Ну, это я бы сказал дело привычки... для людей, что всю молодость провели на PDP-11 и m68K, так вполне даже ничего Я помню, с советского КМ1801 долго переучивался