Вызов функции написанной на asm'е из Си-программы

Тема в разделе "WASM.BEGINNERS", создана пользователем ntp, 13 окт 2008.

  1. ntp

    ntp New Member

    Публикаций:
    0
    Регистрация:
    13 окт 2008
    Сообщения:
    30
    Здравствуйте.
    Хочу вот разобраться как нужно объявлять прототипы процедур в Си написанные, например на masm'е. То есть, проблема такая: Есть объектный файл (COFF), содержащий какую-то функцию(процедуру), он линкуется с программой на Си (VisualStudio) и в программе эта функция вызывается. Чтобы ее вызвать в программе нужно ее объявить, вот с этим я не могу разобраться.
    Вот исходный код функции (masm32):

    .386
    .model flat , stdcall
    option casemap: none
    include \masm32\include\kernel32.inc
    includelib \masm32\lib\kernel32.lib
    PUBLIC qwe
    .data
    msg db "Hello world", 0
    stdout dd 0
    .code
    qwe PROC
    invoke GetStdHandle, -11
    mov DWORD PTR [stdout], eax
    invoke WriteFile, stdout, offset msg, sizeof msg, 0, 0
    ret
    qwe ENDP
    end

    Такой вот объектный файл легко линкуется с другой программой на masm:

    .386
    .model flat , stdcall
    option casemap: none

    include \masm32\include\kernel32.inc
    includelib \masm32\lib\kernel32.lib

    EXTRN qwe@0:NEAR
    .data

    .code
    start:
    call qwe@0
    invoke ExitProcess,0
    end start

    И моя функция вызывается и печатает всем известное словосочетание.

    Если же я пишу основную прогу в Visual C++ и объявляю там функцию(которую буду прилинковывать), то после запуска возникает ошибка:

    LNK2019: unresolved external symbol "void __cdecl qwe(void)" (?qwe@@YAXXZ) referenced in function _main

    Я предположил что компилятор преобразует все имена экспортируемых функций к такому виду: ?<name function>@@YAXXZ и соответсвенно в masme имя функции "qwe" изменил на "?qwe@@YAXXZ", но главная программа попрежнему не видит функцию из прилинкованного объектного файла.

    Просьба к тем кто разбирается во всем этом просвятить меня немного.
     
  2. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    extern "C" пропиши. _stdcall добавь.
    то есть прототип - extern "C" void __stdcall qwe();

    а имя функции в masm-программе поменяй на _qwe.
    в итоге по stdcall-мангингу будет _qwe@0, чего и будет ожидать сишный компилер.


    ps. в заголовке надо было поставить "из С++ программы" ;) изза различия в манглинге у си и с++
     
  3. ntp

    ntp New Member

    Публикаций:
    0
    Регистрация:
    13 окт 2008
    Сообщения:
    30
    Спасибо Great, все заработало.
     
  4. _basmp_

    _basmp_ New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2005
    Сообщения:
    2.939
    для вашего случая в С/С++ пишем объяву

    extern void __stdcall qwe();

    и еще в масме метки объявленные через proc по умолчанию public и stdcall c колвом параметров после слова proc. те внешний public - не нужен.
     
  5. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    _basmp_
    всетаки я настаиваю на extern "C" потому что он плюсовым компилятором собирает ;)
     
  6. _basmp_

    _basmp_ New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2005
    Сообщения:
    2.939
    Great
    да, действительно. я ошибся.