简体   繁体   中英

What is a way to provide logging from a c++ dll to a c# application via interop/pinvoke

I have a C++ DLL that I have source to. It is currently logging to stdout.

I am calling methods in this dll via pinvoke from c#.

I want the c# code to be able to get the log messages, and then forward them to the c# application's own logging mechanism.

I have seen some questions/answers dealing with capturing stdout, but I cannot get them to work. If someone can provide a complete hello world example for this, that would be great.

Otherwise, I was thinking of changing the c++ function to accept a string or stream parameter of some sort and just fill it with messages to be read at the return of the function.

However, how do I use string, since the c++ dll would need to allocate the memory, and what would free it?

Is there a way for me to pass in a stream and read from the stream using normal c# stream mechanics, but inside the dll let it be used just like stdout would be normally?

Help!

This question is close, but I dont want to write it out to a file, if something similar would work to capture into a memorystream that would be great, but I don't see an equivilent SafeHandle etc for memorystream. Redirect stdout+stderr on a C# Windows service

You could declare your logging function in your C++ DLL as a function pointer, which defaults to a function printing to stdout, and provide a P/Invoke'able function to set it to a different callback.
You can pass a C# method to this function by using Marshal.GetFunctionPointerForDelegate .

Example (untested!)

C++ DLL (pseudo-code) :

delegate void logger(char* msg);

logger log = printf;

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

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

C# program:

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();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM