如何在另一个 CRT 库中重新路由 std::clog?
Posted
技术标签:
【中文标题】如何在另一个 CRT 库中重新路由 std::clog?【英文标题】:How to re-route std::clog in another CRT lib? 【发布时间】:2011-05-10 21:39:58 【问题描述】:我有一个用 VS2008 构建的 Win32 程序,所以我的代码与 MSVCR90.DLL 和 MSVCP90.DLL 链接。但是,它也在使用 VS2005 构建的 DLL(我无法修改)中运行代码,并且当该 DLL 中的代码打印到阻塞流时,它通过 MSVCR80.DLL 和 MSVCP80.DLL 执行此操作。这就是问题所在:如果我在代码中重新路由 std::clog,我只会影响针对 crt 9.0 库构建的代码,使用旧 crt 8.0 的代码不会重新路由其输出。那么有没有办法在针对旧 CRT 构建的 DLL 中重新路由阻塞流?
我研究过在旧 CRT DLL 上调用 GetModuleHandle() 和 GetProcAddress() 并设法重新路由 C 标准错误流(通过 _open_osfhandle 和 _dup2),但是 C++ 阻塞流似乎仍然不受影响。我想我还需要在旧的 CRT 库中调用 ios_base::sync_with_stdio() 但我无法获得该函数的有效地址。任何帮助将不胜感激。
谢谢。
【问题讨论】:
【参考方案1】:使用 VS2005 构建一个辅助 DLL - 这个 DLL 应该简单地导出一些函数来进行 VS8 运行时所需的设置。
【讨论】:
谢谢,但我会采用延迟加载 DLL 的方法。【参考方案2】:也可以尝试freopen
...,但这也可能需要在较旧的 CRT 中调用。不过,Eric 对帮助 DLL 的建议太过分了,只需使用 GetProcAddress
获取指向 VC8 版本的指针。
最有效的选择是在启动进程时重定向标准流。
另一种可能性是延迟加载帮助程序 DLL,并在加载之前执行流重定向。这样当 MSVCRT80 加载时,它将附加到重定向的流。
【讨论】:
谢谢,如前所述,我已经尝试过 GetProcAddress 方法,并在标准 C 流(例如 stderr)上取得了一些成功,但无法使其适用于 C++ 流(例如 clog 或 cerr)。我想我还需要在较旧的 CRT 中调用 ios_base::sync_with_stdio() ,但是,获得指向 C++ 名称损坏函数的指针被证明是不可能的(或者我只是做错了!)。我想我会尝试延迟加载的 DLL 方法。对于一开始听起来微不足道的事情,似乎需要做很多工作!以上是关于如何在另一个 CRT 库中重新路由 std::clog?的主要内容,如果未能解决你的问题,请参考以下文章
如何将 Git 存储库转换为嵌套在另一个(父)Git 存储库中的子模块?