Как обеспечить ведение журнала из dll c ++ в приложение c # через interop / pinvoke - PullRequest
1 голос
/ 09 августа 2010

У меня есть C ++ DLL, источник которой у меня есть.В настоящее время он входит в stdout.

Я вызываю методы в этой dll через pinvoke из c #.

Я хочу, чтобы код c # мог получать сообщения журнала, а затем пересылать их всобственный механизм ведения журнала приложения c #.

Я видел несколько вопросов / ответов, касающихся захвата stdout, но я не могу заставить их работать.Если кто-то может предоставить для этого полный пример hello world, это было бы замечательно.

В противном случае я думал об изменении функции c ++, чтобы она принимала какой-либо параметр строки или потока и просто заполняла его сообщениями длябыть прочитанным при возврате функции.

Однако, как мне использовать строку, так как DLL c ++ должен был бы выделить память, и что освободило бы ее?

Есть ли способдля меня, чтобы передать в потоке и читать из потока, используя обычную механику потока C #, но внутри DLL пусть это будет использоваться так же, как обычно, стандартный вывод?близко, но я не хочу записывать это в файл, если что-то подобное будет работать для захвата в поток памяти, что было бы здорово, но я не вижу эквивалентного SafeHandle и т. д. для потока памяти. Перенаправление stdout + stderr в службе Windows C #

1 Ответ

1 голос
/ 09 августа 2010

Вы можете объявить свою функцию ведения журнала в вашей C ++ DLL как указатель на функцию, которая по умолчанию переводит функцию в тип stdout, и предоставить функцию P / Invoke'able, чтобы установить для нее другой обратный вызов.
Вы можете передатьметод C # для этой функции с использованием Marshal.GetFunctionPointerForDelegate .

Пример (не проверено!)

C ++ DLL (псевдокод) :

delegate void logger(char* msg);

logger log = printf;

void set_logger(logger l) {
    log = l;
}

void test() {
    log("Hello World!");
}

C # программа:

static extern void set_logger(IntPtr l);

static extern void test();

static Action<IntPtr> log;

static void LogToConsole(IntPtr msg)
{
    Console.WriteLine(Marshal.PtrToStringAnsi(msg));
}

static void Main()
{
    log = new Action<IntPtr>(LogToConsole);
    set_logger(Marshal.GetFunctionPointerForDelegate(log));

    test();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...