WinApi и extern "C"

Тема в разделе "LANGS.C", создана пользователем Diakon, 14 мар 2010.

  1. Diakon

    Diakon New Member

    Публикаций:
    0
    Регистрация:
    26 июн 2008
    Сообщения:
    27
    В процедурах объявленных как 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" то искожается имя процедуры и сторонние приложения не могут вызвать процедуру по имени.

    Подскажите что делать?
     
  2. Asterix

    Asterix New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2003
    Сообщения:
    3.576
    давайте дизассемблерный листинг как этот код компилируется
     
  3. Diakon

    Diakon New Member

    Публикаций:
    0
    Регистрация:
    26 июн 2008
    Сообщения:
    27
    Код (Text):
    1. .text:641413B2 LoadSnar@12     proc near               ; CODE XREF: sub_64142390+Ap
    2. .text:641413B2
    3. .text:641413B2 var_18          = dword ptr -18h
    4. .text:641413B2 var_14          = dword ptr -14h
    5. .text:641413B2 var_10          = dword ptr -10h
    6. .text:641413B2 var_C           = dword ptr -0Ch
    7. .text:641413B2 arg_0           = dword ptr  8
    8. .text:641413B2 arg_4           = dword ptr  0Ch
    9. .text:641413B2 arg_8           = dword ptr  10h
    10. .text:641413B2
    11. .text:641413B2                 push    ebp
    12. .text:641413B3                 mov     ebp, esp
    13. .text:641413B5                 sub     esp, 18h
    14. .text:641413B8                 mov     [esp+18h+var_C], 0
    15. .text:641413C0                 mov     [esp+18h+var_10], offset aErrorMonstrs ; ""
    16. .text:641413C8                 mov     [esp+18h+var_14], offset aCanTLoadingMon ; ""
    17. .text:641413D0                 mov     [esp+18h+var_18], 0
    18. .text:641413D7                 call    MessageBoxA
    19. .text:641413DC                 sub     esp, 10h
    20. .text:641413DF                 cmp     [ebp+arg_4], 0FFh
    21. .text:641413E6                 jnz     short loc_64141406
    22. .text:641413E8                 mov     ecx, [ebp+arg_8]
    23. .text:641413EB                 mov     edx, dword_64143118
    24. .text:641413F1                 mov     eax, [ebp+arg_0]
    25. .text:641
     
  4. HiroProtagonist

    HiroProtagonist New Member

    Публикаций:
    0
    Регистрация:
    18 сен 2009
    Сообщения:
    9
    .text:641413D7 call MessageBoxA
    .text:641413DC sub esp, 10h

    wtf? ^____^
     
  5. Diakon

    Diakon New Member

    Публикаций:
    0
    Регистрация:
    26 июн 2008
    Сообщения:
    27
    MessageBox отображается без заголовка почти в самом нижнем левом углу. А например FindFirstFile падает с ERROR_NOACCES
     
  6. RET

    RET Well-Known Member

    Публикаций:
    17
    Регистрация:
    5 янв 2008
    Сообщения:
    789
    Адрес:
    Jabber: darksys@sj.ms
    эх манглирование-мухлирование...
    Вызывайте по ординалу. или используйте def-файл:
    Код (Text):
    1. EXPORTS
    2.     Имя_функции, которую манглить не надо
     
  7. AsmGuru62

    AsmGuru62 Member

    Публикаций:
    0
    Регистрация:
    12 сен 2002
    Сообщения:
    689
    Адрес:
    Toronto
    HiroProtagonist верно заметил.
    Dev С++ зачем-то чистит стек после вызова, но MessageBox уже почистил перед выходом.
    Одно слово - бесплатный компилятор!
     
  8. Sol_Ksacap

    Sol_Ksacap Миша

    Публикаций:
    0
    Регистрация:
    6 мар 2008
    Сообщения:
    623
    AsmGuru62
    >Dev С++ зачем-то чистит стек после вызова, но MessageBox уже почистил перед выходом.
    Непохоже. Скорее этот компилятор просто не любит пуши, и сразу после вызова MessageBox'а отменяет то, что эта апи почистила.

    Код (Text):
    1. .text:641413B5                 sub     esp, 18h
    2. .text:641413B8                 mov     [esp+18h+var_C], 0
    3. .text:641413C0                 mov     [esp+18h+var_10], offset aErrorMonstrs ; ""
    4. .text:641413C8                 mov     [esp+18h+var_14], offset aCanTLoadingMon ; ""
    5. .text:641413D0                 mov     [esp+18h+var_18], 0
    6. .text:641413D7                 call    MessageBoxA
    7. .text:641413DC                 sub     esp, 10h                      <- sub, не add!
    Diakon
    Extern "C" в данном случае влияет только на манглирование имени функции. Падает не из-за этого.
     
  9. Diakon

    Diakon New Member

    Публикаций:
    0
    Регистрация:
    26 июн 2008
    Сообщения:
    27
    А в чем может быть дело? Может ли быть дело в каких-то привилегиях?
     
  10. cppasm

    cppasm New Member

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    923
    Diakon
    Выложи бинарник который падает куда-нибудь.
    Желательно в минимальном варианте.

    Комилятор там GCC, и не надо писать ерунду про то что он плохой.
    Я на 200% уверен что ошибка в коде.
     
  11. Diakon

    Diakon New Member

    Публикаций:
    0
    Регистрация:
    26 июн 2008
    Сообщения:
    27
    Проблема решилась. Я ставил хук в коде и прыгал в свою длл . Хук писал на масме и создавал объектный файл, который линковал с++.

    Так вот код в масме

    pusha
    pushf

    преобразовался почему-то в итоге в

    pushad
    pushfw !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    Пришлось уточнять, что я имел в виду.
     
  12. Sol_Ksacap

    Sol_Ksacap Миша

    Публикаций:
    0
    Регистрация:
    6 мар 2008
    Сообщения:
    623
    >pushf
    >pushfw
    Лол. Тоже как-то обожглись именно на этом. Ситуация осложнялась тем, что этот код выполнялся в r0, причём окружение было таково, что невозможна была ни отладка на VM, ни генерация крэшдампа (из-за других наших неверных решений). Таким образом несколько часов пытались понять причину остановов реальной мащины при запуске кода – до тех пор пока внимательно не изучили каждую инструкцию, собранную компилятором msvc из кода инлайн-ассемблера.
     
  13. r90

    r90 New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2005
    Сообщения:
    898
    [offtop]
    И после этого мне будут доказывать, что at&t синтаксис, который приучает для всех команд писать постфиксы, указывающие размер операндов -- это зло. =)
    [/offtop]
     
  14. cppasm

    cppasm New Member

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    923
    В интеловском синтаксисе тоже никто суффиксы ставить не запрещает - но не ставят же. :)
    А в AT&T напрягают проценты дурацкие перед каждым именем регистра и обратный (непривычный) порядок аргументов.
     
  15. Ustus

    Ustus New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2005
    Сообщения:
    834
    Адрес:
    Харьков
    cppasm
    Ну, это я бы сказал дело привычки... для людей, что всю молодость провели на PDP-11 и m68K, так вполне даже ничего :) Я помню, с советского КМ1801 долго переучивался :)