【发布时间】:2022-07-04 14:20:25
【问题描述】:
请在下面查看我的短代码。
包装器.h
#include <stdio.h>
#include <stdarg.h>
extern"C" int mm_printfA(const char *fmt, ...);
extern"C" int mm_printfW(const wchar_t *fmt, ...);
包装器.cpp
#include "pwrapper.h"
int mm_printfA(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
int ret = vprintf(fmt, args);
va_end(args);
return ret;
}
int mm_printfW(const wchar_t *fmt, ...)
{
va_list args;
va_start(args, fmt);
int ret = vwprintf(fmt, args);
va_end(args);
return ret;
}
main.cpp
#include "pwrapper.h"
// cl /MT /D _NO_CRT_STDIO_INLINE main.cpp pwrapper.cpp
void main()
{
mm_printfA("What is %d?\n", 123);
}
#if 0
void usedull()
{
vprintf(NULL, NULL);
vwprintf(NULL, NULL);
}
#endif
由于某种原因,我需要用_NO_CRT_STDIO_INLINE编译它,像这样:
cl /MT /D _NO_CRT_STDIO_INLINE main.cpp pwrapper.cpp
但链接阶段无法说出未解析的外部符号 vwprintf 和 vprintf。
我发现一个非常奇怪的解决方法是:启用usedull() 函数体——尽管从未被调用,并且通过pwrapper.lib 链接,使用下面的 bb.bat:
@setlocal EnableDelayedExpansion
@set CFLAGS=/D _NO_CRT_STDIO_INLINE
cl /nologo /c /MT %CFLAGS% pwrapper.cpp
@if errorlevel 1 exit /b 4
lib /nologo /out:pwrapper.lib pwrapper.obj
@if errorlevel 1 exit /b 4
cl /nologo /c /MT main.cpp
@if errorlevel 1 exit /b 4
link /nologo main.obj pwrapper.lib
@if errorlevel 1 exit /b 4
嗯,这确实有效,但为什么呢?
这不是一个令人愉快的解决方法,因为每个 exe 项目都需要包含一个“无用的”usedull() 函数。那么,有没有更好的办法呢?
我真的不知道为什么这种解决方法有效,非常欢迎对其进行解释。
【问题讨论】:
-
我会首先尝试确定为什么需要定义
_NO_CRT_STDIO_INLINE。您在此处提供的示例不需要它,因为cl /MT main.cpp pwrapper.cpp构建没有问题。 -
嗯,它发生在我编写 KMDF 驱动程序时。我不小心将我自编译的用户模式 mm_snprintf.lib 链接到最终的内核模式 .sys 并且发生了奇怪的行为,并且生成的 .sys 工作正常。最后,我用内核模式头重新编译了mm_snprintf并将其链接到.sys,问题最终消失了。是的,
_NO_CRT_STDIO_INLINE不需要调整。我把问题留在这里记录神秘的usedull()行为。
标签: visual-studio-2019 cl