Я заинтересован в вызове SoX, консольного приложения с открытым исходным кодом, из другой программы с графическим интерфейсом пользователя Windows (естественно написанной на Delphi). Вместо того, чтобы обрабатывать и скрывать окно консоли, я хотел бы просто преобразовать приложение в DLL, которую я могу вызывать из своего приложения.
Прежде чем я начну идти по этому пути, мне интересно, сколько работы мне предстоит выполнить? Мы говорим о крупном предприятии или есть прямое решение? Я немного знаю Си, но ни в коем случае не эксперт.
Я не жду конкретных деталей SoX, просто преобразование консольного приложения EXE в DLL в целом. Если кто-то знаком с SoX, то даже лучше.





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