我在C#中有一个nunit Test,它调用C ++ DLL中函数的C#包装器。 C ++代码使用std :: cerr输出各种消息。
使用nunit-console / out / err或/ xml开关无法重定向这些消息。 在nunit(GUI版本)中,输出不会出现在任何地方。
我希望能够在nunit(GUI版本)中看到此输出。 理想情况下,我希望能够在Test中访问此输出。
感谢您的帮助。
答案 0 :(得分:1)
重定向std :: cerr是用你自己的替换流缓冲区的问题。 在退出之前恢复原始缓冲区很重要。我不知道你的包装器是什么样的,但是你可以弄清楚如何让它读取output.str()。
#include <iostream>
#include <sstream>
#include <cassert>
using namespace std;
int main()
{
streambuf* buf(cerr.rdbuf());
stringstream output;
cerr.rdbuf(output.rdbuf());
cerr << "Hello, world!" << endl;
assert(output.str() == "Hello, world!\n");
cerr.rdbuf(buf);
return 0;
}
答案 1 :(得分:1)
感谢您的提示。 这就是我最终做的事情:
.CPP文件------------------------
#include <iostream>
#include <sstream>
static std::stringstream buffer;
static std::streambuf * savedBuffer = NULL;
extern "C" __declspec(dllexport) bool Redirect()
{
if (savedBuffer)
{
return false;
}
std::streambuf * buf(std::cerr.rdbuf());
std::cerr.rdbuf(buffer.rdbuf());
// This two lines are for illustration purposes only!
std::cerr << "Hello world" << std::endl;
return true;
}
extern "C" __declspec(dllexport) void Revert()
{
if (savedBuffer)
{
std::cerr.rdbuf(savedBuffer);
}
savedBuffer = NULL;
}
extern "C" __declspec(dllexport) const char * getCerr()
{
return _strdup(buffer.str().c_str());
}
extern "C" __declspec(dllexport) void freeCharPtr(char *ptr)
{
free(ptr);
}
.CS文件------------------------------------------
public static class Redirector
{
// PRIVATE ------------------------------------------------------------
private const String LibraryName = "MyCpp.dll";
[DllImport(LibraryName, CharSet = CharSet.Ansi)]
private static extern IntPtr getCerr();
// PUBLIC -------------------------------------------------------------
[DllImport(LibraryName, CharSet = CharSet.Ansi)]
public static extern bool Redirect();
[DllImport(LibraryName, CharSet = CharSet.Ansi)]
public static extern void Revert();
[DllImport(LibraryName, CharSet = CharSet.Ansi)]
internal static extern void freeCharPtr(IntPtr ptr);
public static string GetCerr()
{
IntPtr temp = getCerr();
string result = System.Runtime.InteropServices.Marshal.PtrToStringAnsi(temp);
freeCharPtr(temp);
return result;
}
}
NUnit测试-----------------------
[Test]
// [Ignore]
public void TestRedirect()
{
Redirector.Redirect();
// Call more functions that output to std::cerr here.
Redirector.Revert();
System.Console.WriteLine(Redirector.GetCerr());
}
freeCharPtr()的东西是从_strdup()释放分配的内存所必需的,因为我无法解决(如果它甚至可能)如何编组std :: string。
注意:这不是线程安全的!