如何在源代码中查找所有非 Unicode 函数调用

Posted

技术标签:

【中文标题】如何在源代码中查找所有非 Unicode 函数调用【英文标题】:How to Find all non-Unicode Function Calls in Source Code 【发布时间】:2013-11-01 17:56:56 【问题描述】:

在我的源代码中,我一直非常小心地使用 Unicode,总是调用宽版本的 WinAPI 函数,在我的转换等方面非常小心,以支持我的程序的许多用户使用非英文副本窗户。

但是我相信你们都可以理解错误会逐渐蔓延。我最近遇到了一个程序崩溃,在我的代码中只有一个地方,我将函数称为“isspace”而不是“iswspace”。

是否有一些工具可以让我扫描我的源代码以查找所有 ANSI 函数调用,希望能找到更多可能存在的错误?

谢谢。

【问题讨论】:

列出所有 ANSI 函数调用并在源代码树中使用 grep? 首先定义UNICODE_UNICODE 查看最终可执行文件(或 DLL)的符号表而不是源代码可能更容易。这样,您将只看到每个使用的 API 函数一次。您可以手动扫描该列表,然后将其保存为已批准,然后仅定期将差异扫描到已批准列表中。如果您喜欢这种方法,我可以将此评论变成答案。 我会做同样的“MvG”。但是我会看一下目标文件:我会编译程序并为每个目标文件使用 GNU MingW Binutils “objdump -t file.obj”。这将打印目标文件所需和定义的所有符号的列表。我会在输出中搜索以大写“A”结尾的函数名称(如“MessageBoxA”)。如果我有大量的目标文件,我会写一个小程序来做。 如果你使用 gcc,你总是可以使用毒 pragma 来得到编译错误,只要你不小心使用了一个你从未打算使用的符号:gcc.gnu.org/onlinedocs/cpp/Pragmas.html 【参考方案1】:

我在不久前正在开发的软件中遇到问题。我发现问题是由 strcpy()、strcat() 等各种没有保护的字符串函数引起的,如果源出于任何原因出现问题,它们可能会覆盖目标缓冲区。

我当时所做的是编写一个 C 解析器(当时我正在使用 C...)并检测到所有函数调用(这在 C 语法中很容易:'(' is a function call if within a block . 在 C++ 中,您也必须检测类和结构,但这并没有更多的工作。)现在您可以在您的软件不应该使用的任何功能上生成错误,这会破坏您的构建。

免费的 C++ 解析器“无处不在”,因此您可以使用其中一个并重用该代码。

现在,还有另一种使用预处理器的方法:对于您不希望软件使用的任何功能,您可以创建一个#define,使用时会产生错误:

#define isspace function-error "please use iswspace() instead of isspace()"

当然,这意味着您首先需要知道这些函数的列表,正如其他人所提到的,您可以通过查看动态库链接表来找到。但结果是,如果不先修复一些问题,您将无法编译您的软件。一个问题,您必须在最后包含的头文件中执行此操作,否则您的库头文件可能会出现一些问题:

#include <boost/shared_ptr.hpp>
#include <non_unicode_function.h>
... your functions ...

这可能比 C++ 解析器更简单,但它也可能没有那么有趣……然而,如果你偶尔需要调用一个禁止的函数,你可以做一个 #undef 来清楚地记录,等等。并在之后恢复该值。

【讨论】:

【参考方案2】:

我现在已经从 cplusplus.com 编译了一个 ANSI 函数列表。请注意其局限性,尤其是:

a) 这不包括任何形式为“...A”的 WinAPI 函数。 b) 它不包括任何使用 Microsoft 命名约定的 C 函数。 c) 我可能犯了一些错误。

但是,我希望它会被证明是有用的,并且社区将帮助纠正我可能犯的任何遗漏或错误。

isalnum
isalpha
isblank 
iscntrl
isdigit
isgraph
islower
isprint
ispunct
isspace
isupper
isxdigit
tolower
toupper
to_string
fprintf
fscanf
printf
scanf
snprintf 
sprintf
sscanf
vfprintf
vfscanf 
vprintf
vscanf 
vsnprintf 
vsprintf
vsscanf 
fgetc
fgets
fputc
fputs
getc
getchar
gets
putc
putchar
puts
ungetc
strtod
strtof 
strtol
strtold 
strtoll 
strtoul
strtoull 
memcpy
memmove
memchr
strchr
strcspn
strpbrk
strrchr
strspn
strstr
strtok
memcmp
strcmp
strcoll
strncmp
strxfrm
strcat
strncat
memset
strlen
strftime
regex
cmatch
smatch
csub_match
ssub_match
isctype
toctrans
ctrans
ctype
ctrans_t
ctype_t
int_t
char
EOF

【讨论】:

以上是关于如何在源代码中查找所有非 Unicode 函数调用的主要内容,如果未能解决你的问题,请参考以下文章

无法在函数内调用非内置函数

FCC 练习 - Caesars Cipher(关于用Unicode查找字符串的操作)

如何在非托管 c++ dll 中查找调用方程序集名称

非托管 DLL 函数的正确调用约定

如何调用 DLL 的非导出函数?

C语言遍历目录中的文件