Как интегрировать программу с открытым исходным кодом на C вместо вызова ее исполняемого файла через системный вызов? - PullRequest
1 голос
/ 25 декабря 2010

У меня есть исполняемый файл (ископаемое scm), который вызывается моей программой извне через вызов Windows :: CreateProcess. Затем выводятся stdout и stderr. Поскольку исходный код ископаемого доступен, я бы предпочел создать из него статическую библиотеку и напрямую выполнять вызовы. В настоящее время связь с ископаемыми осуществляется через параметры командной строки, а обратная связь - через код возврата процесса, stdout и stderr. Fossil пишет в stdout / err через вызовы printf и fprintf.

Как лучше всего решить эту проблему с минимальным изменением ископаемого источника? Есть ли надежный и кроссплатформенный способ перехвата stdout / err и отправки его в буфер памяти?

Ответы [ 3 ]

3 голосов
/ 25 декабря 2010

Вы говорите, что хотите

перехватить stdout / err и отправить его в буфер памяти

Это будет означать, что вы не хотите вводить API для программы SCM, а вместо этого хотите продолжить синтаксический анализ текстового вывода без изменения существующего кода. Если это так, то я не вижу смысла менять ваш нынешний подход. Что именно должно быть получено при использовании буфера памяти и статического связывания по текущему подходу?

3 голосов
/ 25 декабря 2010

Вы можете сделать это в следующих шагах:

  • Переименуйте основную функцию окаменелости во что-то другое, чтобы ее можно было назвать
  • Перед вызовом главного ископаемого, перенаправьте stdout / stderr в файл по вашему выбору с помощью:

freopen("filename.out", "w", stdout);

  • Сформируйте массив аргументов, вызовите fossil_main, прочитайте вывод из файлов.
  • Вам необходимо восстановить состояние потока stdout; для этого нет кроссплатформенного механизма, но вы можете использовать некоторые псевдо-дескрипторы (например, CONOUT $ в Windows).

Тем не менее, обратите внимание, что это хрупкое:

  • Могут быть глобальные переменные, которые должны быть инициализированы нулями в начале main (), что не будет истинно для второго вызова main ()
  • Ископаемое может изменить состояние какого-либо процесса / потока (локаль, текущий каталог и т. Д.), Вы не сможете его надежно восстановить. Особенно плохим случаем этого является вызов exit (n).
  • Не будет обычной очистки при завершении процесса - ожидайте, что дескрипторы файлов остаются открытыми (чтобы вы не смогли открыть их снова, если они открыты без общего доступа), утечки памяти и т. Д.
  • Очевидно, что теперь с сбоями / зависаниями в окаменелости будет труднее справляться (иногда вы можете обойти это)

Как правило, вы можете сделать это, но не делайте этого, если у вас нет веских оснований (т.е. для производительности), и вы не готовы к последствиям и исправлению ошибок самостоятельно.

0 голосов
/ 25 декабря 2010

Превратите ископаемое в общую библиотеку, а затем используйте это из своей пользовательской программы.

...