从动态库调用fprintf(c ++)

时间:2012-08-02 22:50:08

标签: c++

我正在创建一个包含日志记录类的Windows DLL库,该类中的日志函数只是为了测试目的而调用fprintf:

fprintf(stderr,“DEBUG:%s \ n”,“你好”);

现在这个调用工作正常,如果我在我的其他项目(使用库)中的任何文件中的任何函数中使用它,但是如果我把它放在我的库中的任何日志类中它只是不打印任何东西。
我可以看到它正确运行函数(使用简单的退出(0);测试)。

现在我仍然对c / c ++中的整个图书馆概念有点新意,所以可能有些东西我不明白,但我不知道为什么它不起作用。

我尝试在这里和谷歌搜索,但我找不到其他人有同样的问题 我使用VC ++ 2010

编辑:我想到了传递filepointer而不是仅使用库中的stderr,这会导致抛出异常(抛出时文件的_tmpfname指针为NULL,我不确定是对的)

1 个答案:

答案 0 :(得分:2)

我会避免为任何生产代码执行此操作(虽然可以测试)。标准I / O流属于应用程序,the DLLs are guests in the house。如果要提供调试输出,请允许应用程序设置用于记录的回调函数,例如:

// In your DLL's header file:
typedef void (*LogFunc)(const char *, ...);
void DLLEXPORT SetLogFunction(LogFunc logFunc);

// In your DLL's source file:
LogFunc g_LogFunc;
void DLLEXPORT SetLogFunction(LogFunc logFunc)
{
    g_LogFunc = logFunc;
}

...
// Then, instead of calling fprintf(stderr, "blah"), do this:
g_LogFunc("blah");

如果您只是为测试而执行此操作,则可以直接写入stderr,但请记住,DLL和应用程序必须链接到相同版本的C运行时才能实现工作。 C运行时本身就是一个DLL,如果你的DLL和应用程序指定不同版本的C运行时,你最终会将C运行时的两个独立副本加载到内存中,每个副本都有自己对{{1}的概念。意味着。当它们不同时,会发生不好的事情。

在Visual Studio中,要设置您正在使用的C运行时库,请打开项目设置并转到配置属性→C / C ++→代码生成→运行时库,并确保两者都有DLL和应用程序设置为完全相同的值(通常为“多线程DLL(/ MD)”或“多线程调试DLL(/ MDd)”,具体取决于您是否正在构建调试版或发布版)