【发布时间】:2021-03-18 20:48:33
【问题描述】:
我正在使用一个 C++ DLL,我通过 C# 代码中的 P/Invokes 访问它。问题是我无法将非托管端发生的 std 错误重定向到文件。如果构建处于 DEBUG 中,但当构建处于 RELEASE 中时,STD logfile-unmanaged 不包含错误但包含且不关闭应用程序,它会像没有错误一样继续运行:
Before Error
After Error
在 C++ 中,STD 错误被重定向到如下文件:
extern "C" __declspec(dllexport) void RedirectStd()
{
int fileNO = _fileno(stderr);
_close(fileNO);
int file = _open("logfile-unmanaged", O_CREAT | O_RDWR, 0644);
_dup2(file, fileNO);
}
C++ 中的运行时错误是这样生成的:
extern "C" __declspec(dllexport) void DoException()
{
fprintf(stderr, "Before Error\n");
int a = 0;
int b = 10 / a;
fprintf(stderr, "After Error\n");
}
在 C# 中,我调用了这两种方法:
[DllImport("TestError.dll", CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
internal static extern void RedirectStd();
[DllImport("TestError.dll", CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
internal static extern void DoException();
我的主要功能:
[HandleProcessCorruptedStateExceptions]
[SecurityCritical]
static void Main(string[] args) {
Console.WriteLine("===== REDIRECT =====");
Console.WriteLine("Native/Unmanaged exception redirected to logfile-unmanaged.");
RedirectStd();
Console.WriteLine("Native/Unmanaged std error redirected.");
Console.WriteLine("");
Console.WriteLine("===== EXCEPTION =====");
DoException();
Console.WriteLine("Waiting for program to crash");
do {
} while (true);
}
编辑:
C# 控制台应用程序: 程序.cs
using System;
using System.Runtime.ExceptionServices;
using System.Runtime.InteropServices;
using System.Security;
namespace ConsoleWithErrors {
class Program {
[DllImport("TestError.dll", CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
internal static extern void RedirectStd();
[DllImport("TestError.dll", CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
internal static extern void DoException();
[HandleProcessCorruptedStateExceptions]
[SecurityCritical]
static void Main(string[] args) {
RedirectStd();
DoException();
Console.WriteLine("Waiting for program to crash");
do {
} while (true);
}
}
}
控制台应用程序保持打开状态,就像在非托管端没有错误一样。
【问题讨论】:
-
日志文件的路径是什么?路径名可能无效或无法创建文件。
-
路径名是相对的,日志文件被创建并且它只打印“Before Error\nAfter Error”。虽然错误应该明显在两条消息之间。
-
日志文件的时间戳是你运行应用的时间吗?
-
可能不相关,但为什么在两种 C# 方法中都返回字符串?也应该是无效的。
-
@jdweng 是的,如果我删除文件,它将自动创建。