Однако, если я попытаюсь запустить эту программу в WINE на Oracle Linux,
вывод, который я получаю:
000f:fixme:service:scmdatabase_autostart_services Auto-start service L"MountMgr" failed to start: 2
000f:fixme:service:scmdatabase_autostart_services Auto-start service L"WineBus" failed to start: 2
wine: Bad EXE format for Z:\home\teo.samarzija\Documents\Assembly\debug.exe.
Ошибка "Bad EXE format" - это нечто совершенно иное. Это не означает, что проблема заключается в отсутствующей импортированной функции. Загрузчик никогда не заходил так далеко. Он даже не смог прочитать ваш двоичный файл. Это очень вероятно вызвано несоответствием битности. Например, попытка запустить 64-разрядное приложение в 32-разрядной системе.
Помимо этой проблемы, стоит отметить, что попытка использования функций библиотеки времени выполнения C по своей природе непереносима. может работать, если Wine (или любая другая среда выполнения) предоставляет функцию с идентичной подписью, но, скорее всего, не будет.
Полагаю, мне следует уточнить, так как вызов "1012 * * стандартной функции библиотеки времени выполнения библиотеки" непереносимой "может вызвать недоумение. Эти функции переносимы на уровне исходный код , но не на уровне двоичный . Даже без дополнительной сложности Wine функции библиотеки времени выполнения C являются непереносимыми, поскольку CRT от Microsoft имеет версию - вы должны ссылаться на соответствующую версию и иметь эту DLL-библиотеку доступной во время выполнения или вашего приложения. не сработает.
Именно из-за этой проблемы Windows предоставляет оболочки для этих стандартных функций как часть API базовой платформы, которая доступна повсеместно. Если вы хотите быть полностью переносимым для всех реализаций среды Win32, и вы не ссылаетесь на свою собственную копию библиотеки времени выполнения C, вам следует вместо этого вызывать эти функции.
Версия sprintf
для Win32: wsprintf
. Он имеет тот же интерфейс, что и sprintf
, так что вы можете назвать его так же, как замену. Фактически, хотя вы не должны полагаться на это, он реализован в Windows как простая оболочка для версии sprintf
, предоставляемой локальной копией библиотек времени выполнения C.
Если вам нужна версия, в которую вы можете передать список аргументов (например, vsprintf
), вы можете позвонить wvsprintf
.
Обратите внимание, что в отличие от большинства функций Windows API, эти функции используют соглашение о вызовах __cdecl
, а не соглашение о вызовах __stdcall
. Убедитесь, что вы придерживаетесь этого в коде сборки. Короче говоря, это означает передачу аргументов справа налево и очистку стека на сайте вызовов.
Однако Microsoft отказалась от этих функций, поскольку они не совсем безопасны (возможны переполнения буфера и т. Д.). В качестве замены они предлагают функции в заголовке StrSafe.h
. Эти функции бывают двух вариантов: те, которые принимают количество байтов (Cb
) и те, которые принимают количество символов (Cch
). Относящиеся к этому обсуждению будут либо StringCbPrintfA
, либо StringCchPrintfA
. Однако их сложнее использовать на ассемблере, потому что они предназначены для использования встроенным путем простого включения заголовочного файла StrSafe.h
. Вы можете использовать их в виде библиотеки, но тогда вам нужно будет передать соответствующие заглушки StrSafe.lib
компоновщику. Обратите внимание, что ссылка на эту библиотеку означает, что ваше приложение будет работать только в Windows XP с пакетом обновления 2 или более поздней версии.
Это приведет вас на полпути. Вы на самом деле пытаетесь позвонить printf
, а не sprintf
. Разрыв, конечно же, заключается в получении отформатированной строки, записанной в консоль. Если у вас есть отформатированная строка (сгенерированная wsprintf
, StringCchPrintfA
или любым другим), это можно сделать, вызвав функцию WriteConsole
, которая является Win32 API для записи вывода в консоль. окно. Если вы хотите STDOUT, вам сначала нужно открыть этот дескриптор с помощью GetStdHandle(STD_OUTPUT_HANDLE)
.