Альтернатива для использования system () в C ++ для предотвращения запуска новых процессов - PullRequest
0 голосов
/ 28 марта 2012

Я наткнулся на программу на C ++ для моего использования, в которой выполнялась некоторая обработка с использованием некоторых файлов и файлов exe. Внутри моей программы на C ++ у меня был фрагмент вроде

system(exe1 exe2 > TestFile1.txt  exe3 > TestFile2.txt)
system(exe2 exe3 > TestFile3.txt  exe3 > TestFile4.txt)
system(exe3 exe2 > TestFile5.txt  exe3 > TestFile6.txt)
system(exe4 exe1 > TestFile7.txt  exe3 > TestFile8.txt)

Теперь я сгенерировал .dll из этой программы на C ++ для использования в моем приложении на C # через P / Ivoke (Dllimport), но поскольку в C ++ были использованы эти system, он запускает разные процессы и новый cmd Windows, когда я использую это .dll в моей программе C #.

Я подумал избавиться от этого, сгенерировав dll для всех exe (exe1, exe2, exe3 и т. Д.) И запустив главную функцию из этих dll, но мне не кажется, как я это сделаю в программе на C ++?

Я могу экспортировать основную функцию из C ++ (exe1 dll, exe2 dll, exe3 dll и т. Д.) И вызывать ее через C # P / Invoke, но я хочу такую ​​альтернативу для C ++. заменить вышеуказанный фрагмент из 4 строк. Как это можно сделать?

Ответы [ 2 ]

1 голос
/ 28 марта 2012

Вы можете запускать процессы (также те, которые работают в текстовом режиме), не открывая окно консоли.Пожалуйста, не забрасывайте меня подробностями, поскольку прошло уже много лет с тех пор, как я делал это в последний раз (в Windows я делаю это на обычных условиях в * nix системах).Что я могу вам сказать, так это то, что вы должны изучить функцию CreateProcessEx.Вам также придется переопределить перенаправление stdout в эти текстовые файлы.

Я настоятельно рекомендую не помещать эти процессы в библиотеки DLL, потому что тогда они попадут в адресное пространство вашего основного процесса, а будет испортить ситуацию (кстати: вы можете загружать EXE-файлы, как если бы они были DLL-библиотеками, но вызов их входной функции будет мешать вашему основному процессу, поэтому не делайте этого).

0 голосов
/ 28 марта 2012

Если вопрос о том, что вы публикуете эту консоль, отображается, просто сделайте ваш exe1 ... exeN невидимым. Самый простой способ - заменить

int main(int argc, char **argv)

с

int WINAPI WinMain(
  HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)

И смените цель с консольного приложения на приложение Windows.

Другое (и лучшее решение) - преобразование приложения в несколько библиотек DLL с функциями - это более элегантно и гибко.

EDITED

После прояснения проблемы: «Как я тогда вызываю функции в этих dll?» короткий ответ: вам нужна функция экспорта из каждой dll exe1, .. exeN. Полный ответ - следуйте инструкциям:

В вашей dll объявите

extern "C" __declspec(dllexport) SameNameForAllDllFunction(LPCWSTR fileName){ ...

Это создаст функцию, которую можно экспортировать по имени _SameNameForAllDllFunction. Обратите внимание, что имя файла - Unicode - это упростит связь с C #.

Теперь давайте напишем часть C #:

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void DoSomeWithFile(String fileName);

Это объявляет тип функции. И код вызова:

IntPtr pDll = NativeMethods.LoadLibrary(@"exe1.DLL");
//here MUST go error handlers
try{
    IntPtr pAddressOfFunctionToCall = NativeMethods.GetProcAddress(
        pDll, "SameNameForAllDllFunction");
    //here MUST go error handlers
    DoSomeWithFile dllFunct = (DoSomeWithFile)Marshal.GetDelegateForFunctionPointer(
        pAddressOfFunctionToCall, typeof(DoSomeWithFile)); 
    dllFunct("TestFile1.txt"); //now call the function 
} finally {
    NativeMethods.FreeLibrary(pDll);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...