NUnit不捕获std :: cerr的输出

时间:2010-03-25 05:41:19

标签: c# c++ nunit

我在C#中有一个nunit Test,它调用C ++ DLL中函数的C#包装器。 C ++代码使用std :: cerr输出各种消息。

使用nunit-console / out / err或/ xml开关无法重定向这些消息。 在nunit(GUI版本)中,输出不会出现在任何地方。

我希望能够在nunit(GUI版本)中看到此输出。 理想情况下,我希望能够在Test中访问此输出。

感谢您的帮助。

2 个答案:

答案 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。

注意:这不是线程安全的!