Конвертируйте консольный exe-файл в dll на C
Вопрос
Я заинтересован в том, чтобы позвонить Сокс, консольное приложение с открытым исходным кодом, из другой программы с графическим интерфейсом Windows (написанной, естественно, на Delphi).Вместо того чтобы иметь дело с очисткой и скрытием окна консоли, я хотел бы просто преобразовать приложение в библиотеку DLL, которую я могу вызывать из своего приложения.
Прежде чем я начну идти по этому пути, мне интересно, сколько работы мне предстоит проделать?Мы говорим о крупном предприятии или есть прямое решение?Я немного знаю язык Си, но ни в коем случае не являюсь экспертом.
Я не ожидаю конкретных деталей SoX, просто преобразования консольного приложения EXE в DLL в целом.Но если кто-то знаком с SoX, то еще лучше.
Решение
Что касается конкретной темы превращения консольного исполняемого файла в библиотеку путем изменения исходного кода C, то это зависит от того, как учитывается приложение командной строки.Если это написано таким образом, что ввод-вывод осуществляется через небольшой набор функций или, что еще лучше, указателей на функции, то, очевидно, это будет тривиально.
Если все это делается с помощью printf, scanf и friends, то вам, вероятно, будет лучше всего найти / создать включаемый файл, который включают все исходные файлы, и добавить макрос, который перенаправляет printf / scanf и friends на ваши собственные функции, написанные таким образом, чтобы они соответствовали реализации DLL.Такие вещи, как printf, могут быть созданы из vsnprintf (используйте n-версию для безопасности), поэтому вам не нужно переопределять всю подсистему ввода-вывода C RTL.Однако vsscanf не существует, но в Интернете есть сторонние реализации.
Если в коде используются fprintf, fscanf и т.д.чтобы включить косвенное взаимодействие между файлами и консолью, вам по-прежнему не повезло.Файловая структура непрозрачна, и, в отличие от текстовых файлов Pascal, драйвер переносимого текстового файла не может быть реализован.Это все еще может быть возможно, если вы введете спеланк в свой конкретный C RTL, но вам было бы лучше посоветовать пойти по пути макроса и переопределить свой собственный переименованный тип ФАЙЛА.
Наконец, подход "popen()" возможен в Delphi и несколько упрощен в Delphi 2009 с классами TTextReader и TTextWriter.Объедините их с TFileStream, обернутым вокруг каналов, и укажите каналы для стандартного ввода, стандартного вывода и стандартной ошибки в новом процессе и STARTF_USESTDHANDLES и т.д., и это сработает.Если вам не хочется писать свой собственный, в Интернете также есть сторонние эквиваленты / образцы для Delphi. Вот один из них.
Другие советы
В Windows вы просто вызываете Процесс создания с помощью командной строки SoX.Я не знаю привязок Delphi для Win32, но я делал именно это как в Win32, так и в C #.
И теперь, когда вы знаете, что вы хотите вызвать CreateProcess, поиск в Google о том, как это сделать с помощью Delphi, должен выдать вам весь необходимый код.
Статья на Delphi Corner - Использование CreateProcess для выполнения программ
Возможно, вам даже не понадобится библиотека DLL, вы можете использовать попен() функция для запуска консольного приложения и сбора любого выходного текста.
Отказ от ответственности:Я ничего не знаю о "Сокс".Возможно, код структурирован таким образом, чтобы упростить это, или это может быть сложнее.В любом случае, процесс один и тот же:
Сначала вы хотите найти функции в приложении SoX, которые вы хотите вызвать.Скорее всего, в консольном приложении есть код для анализа командной строки и вызова соответствующих функций.Итак, прежде всего, найдите функции, которые вы хотите использовать.
Далее, ознакомьтесь с информацией об экспорте функций в библиотеки DLL из C на этом сайте: Создание и использование библиотек DLL
Затем создайте новый makefile или файл проекта Visual Studio с целевой библиотекой DLL и добавьте исходные файлы из программы SoX, которые вы изменили для экспорта.
Запустите процесс так, как посоветовал Indiv, и зафиксируйте результат, как показал Адам.
Однако, если вы все еще хотите выполнить преобразование библиотеки DLL, это поможет вам начать
- Настройте SOX для Windows и скомпилируйте его
- Создайте пустой проект DLL с помощью вашего инструмента C ++
- Добавьте файлы SOX, чтобы они стали частью проекта
Добавьте новую функцию под названием DllMain
BOOL APIENTRY DllMain( ОБРАБАТЫВАЕТ hModule, DWORD ul_reason_for_call, LPVOID) {возвращает TRUE;}
Добавьте файл .DEF (используйте название проекта в качестве имени файла), в котором перечислены экспортируемые файлы в DLL - добавьте в него следующее содержимое
LIBRARY "name.DLL"
ЭКСПОРТ
Звоните по-ПРЕЖНЕМУ ЧАСТНЫМ ОБРАЗОМ
Переименуйте main из SOX в CallOldMain
Напишите пользовательскую функцию для регистрации ошибки вывода / возврата и т.д.
Найдите все printfs / cout в приложении SOX и замените его вызовами вашей пользовательской функции выше
Как только библиотека DLL скомпилирована, теперь вы можете вызвать функцию CallOldMain с теми же параметрами, которые ожидают основные программы C.Вы могли бы изменить эту подпись, чтобы возвращать ошибки / выходные данные, указанные выше.
Вы не упоминаете, что представляет собой ваш набор инструментов, но если вы настраиваете gcc в Windows, вы можете использовать обычный config;make;make install, чтобы просто скомпилировать sox.В процессе он создаст dll-файл и консольное приложение.Или вы можете просто указать цель make, чтобы создавать только библиотеку dll.Это скомпилирует собственную библиотеку Windows, которая зависит только от библиотеки DLL MS C runtime, и вы можете использовать ее в своем собственном приложении.
Вы можете запустить консольное приложение и получить его выходные данные с помощью каналов.Вы используете одну сторону канала в качестве стандартного вывода для CreateProcess и считываете с другой стороны как обычный файл.
Вы можете увидеть рабочий пример, написанный на delphi, здесь: http://delphi.about.com/cs/adptips2001/a/bltip0201_2.htm