我可以将输出从 C DLL 重定向到我的 c# log4net 输出吗?
Can I redirect output from a C DLL into my c# log4net output
我有一个C#应用程序,它反过来加载一个C或C++dll(反过来加载其他C/C++ dll)。 在 C# 应用程序中,我使用 log4net 记录器将所有输出捕获到一系列日志文件中。 我的应用程序作为 Windows 服务运行,因此没有控制台/输出窗口供正常的 printfs 或写入 stdout/stderr 的输出转到。
有没有办法将 C# 应用程序设置为定向 stdout/stderr(来自 DLL)并将每一行转换为 log4net 输出。 或者C/C++ DLL中是否有某种方法可以将stdout/stderr流连接到log4net输出?
我找到了一些解决方案(这里:http://bytes.com/topic/c-sharp/answers/822341-dllimport-stdout-gets-eaten),表明我需要像这样对我的 C DLL 进行调用: setvbuf(stdout, NULL, _IONBF, 0);
虽然,我不知道它做了什么,但它没有做我想要的。 我想我也需要一个类似的 stderr 行。 无论哪种情况,谷歌似乎都认为这些行只是负责缓冲,而不是重定向到log4net。
我假设我需要某种函数覆盖来阻止控制台写入(从另一种语言加载的 DLL)并将它们转换为mLog.InfoFormat("{0}", consoleString);
类型的调用。 我是 c# 的新手,甚至不确定要谷歌什么术语才能找到这样的覆盖(如果可能的话)。
不确定这是否会使问题复杂化,但我的 C# 应用程序是多线程的,并且某些 DLL 也具有多个线程。 我认为这只是意味着我需要在处理控制台输出并将其写入 log4net 框架(也许)的方法中具有某种锁,或者 log4net 的正常序列化将为我处理它。
一旦我想出如何使用它们,这些就起作用了。 我设置了两个命名管道(或同一管道的两端? 一个我连接到stdout,并让它在log4net中对通过管道发送的任何内容的日志消息。
internal static void InfoLogWriter(Object threadContext)
{
mLog.Info("InfoLogWriterthread started");
int id = Process.GetCurrentProcess().Id; // make this instance unique
var serverPipe = new NamedPipeServerStream("consoleRedirect" + id, PipeDirection.In, 1);
NamedPipeClientStream clientPipe = new NamedPipeClientStream(".", "consoleRedirect" + id, PipeDirection.Out, PipeOptions.WriteThrough);
mLog.Info("Connecting Client Pipe.");
clientPipe.Connect();
mLog.Info("Connected Client Pipe, redirecting stdout");
HandleRef hr11 = new HandleRef(clientPipe, clientPipe.SafePipeHandle.DangerousGetHandle());
SetStdHandle(-11, hr11.Handle); // redirect stdout to my pipe
mLog.Info("Redirection of stdout complete.");
mLog.Info("Waiting for console connection");
serverPipe.WaitForConnection(); //blocking
mLog.Info("Console connection made.");
using (var stm = new StreamReader(serverPipe))
{
while (serverPipe.IsConnected)
{
try
{
string txt = stm.ReadLine();
if (!string.IsNullOrEmpty(txt))
mLog.InfoFormat("DLL MESSAGE : {0}", txt);
}
catch (IOException)
{
break; // normal disconnect
}
}
}
mLog.Info("Console connection broken. Thread Stopping.");
}
还有一个函数可以将所有这些推送到另一个线程,这样当它命中各种阻塞调用时,它就不会阻塞我的主线程。
internal static void RedirectConsole()
{
mLog.Info("RedirectConsole called.");
ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(InfoLogWriter));
// TODO enqueue and item for error messages too.
}
我在断开连接时遇到问题,必须重新连接管道,但我会想出重新连接解决方案。 我猜当 DLL 从内存中交换回来时,或者当我需要读取但当前没有任何准备读取的内容时,就会发生这种情况? 我还必须设置另一对来阻止 stderr 并重定向它,使用该对的错误日志。 可能想摆脱幻数(-11)并使用普通枚举(STD_ERROR_HANDLE等)
- 为什么我的代码在输出中增加了93天
- 在我的代码中,获得最大的Pair Wise产品C++和输出并不总是正确的
- 为什么我的C++程序的程序集输出充满了 .ascii,没有汇编代码?
- 为什么我的 if else 语句不起作用并从数组中输出正确的索引?
- 这是使用回溯的 nqueen 问题,但我使用了动态 2d 数组,我的程序编译良好,但不返回任何输出
- 我的输出中有一个额外的 0,为什么会这样
- 为什么我的 cout 在输出中没有显示字符串?
- 为什么即使使用 for 循环遍历我的向量,它也没有输出到控制台?(C++)
- 为什么我的输出与输入不同?(C++)
- 当使用我在一个函数、另一个函数中修改的数组时,在我的输出中得到一个奇怪的负数
- 为什么我的代码块上没有显示输出?
- "Program ended with exit code: 0"出现在我的输出的开头?
- gdb 中的列表命令不输出我编写的代码
- 我的代码中是否有任何类型的错误,因为它没有给出正确的输出
- 我的 cout 上有一个奇怪的输出,它把答案放在第一位,然后在我调用它的地方放一个奇怪的输出.我该怎么办?
- 我的求解(字符串 a、字符串 b)的输出与随机哈希中的预期输出不匹配
- fftw:为什么我的 2D DFT 输出与每行的 1D DFT 输出不同?
- 即使我的代码没有错误,我也没有得到正确的输出
- 为什么这一行不输出我的文本文件?
- 在任何情况下都会出现意外输出.我的解决方案出了什么问题