任何用于测试扩展 C/C++ 的实用程序#定义宏?

发布于 2024-09-05 14:32:00 字数 770 浏览 3 评论 0原文

看来我经常花费太多时间试图让#define 宏完全按照我想要的方式进行。我将在下面发布我当前的困境,感谢任何帮助。但真正更大的问题是,是否有人可以推荐任何实用程序来快速显示宏实际上在做什么?如果我能看到问题所在,那么即使是缓慢的试错过程也会变得更快。

目前,我正在从我制作的 DLL 中动态加载一长串函数。按照我设置的方式,函数指针与导出函数具有相同的名称,并且用于原型化它们的 typedef 具有相同的名称,但前面带有下划线。所以我想使用定义来简化一长串函数指针的赋值。

例如,在下面的代码语句中,“hexdump”是 typedef 函数点的名称,也是函数的名称,而 _hexdump 是 typedef 的名称。如果 GetProcAddress() 失败,则失败计数器会递增。

if (!(hexdump = (_hexdump)GetProcAddress(h, "hexdump"))) --iFail;

因此,假设我想用宏替换上面的每一行,就像这样......

GETADDR_FOR(hexdump )

这是迄今为止我想到的最好的。它不起作用(我的//评论只是为了防止消息中的文本格式)...

// #define GETADDR_FOR(a) if (!(a = (#_#a)GetProcAddress(h, "/""#a"/""))) --iFail; 

再说一次,虽然我很高兴了解我犯了哪些愚蠢的错误,但这将使我有一天只需插入我的宏,它就会向我显示我的方法的错误。

It seems I often spend way too much time trying to get a #define macro to do exactly what i want. I'll post my current dilemma below and any help is appreciated. But really the bigger question is whether there is any utility someone could recommend, to quickly display what a macro is actually doing? It seems like even the slow trial and error process would go much faster if I could see what is wrong.

Currently, I'm dynamically loading a long list of functions from a DLL I made. The way I've set things up, the function pointers have the same nanes as the exported functions, and the typedef(s) used to prototype them have the same names, but with a prepended underscore. So I want to use a define to simplify assignments of a long long list of function pointers.

For example, In the code statement below, 'hexdump' is the name of a typedef'd function point, and is also the name of the function, while _hexdump is the name of the typedef. If GetProcAddress() fails, a failure counter in incremented.

if (!(hexdump = (_hexdump)GetProcAddress(h, "hexdump"))) --iFail;

So let's say I'd like to replace each line like the above with a macro, like this...

GETADDR_FOR(hexdump )

Well this is the best I've come up with so far. It doesn't work (my // comment is just to prevent text formatting in the message)...

// #define GETADDR_FOR(a) if (!(a = (#_#a)GetProcAddress(h, "/""#a"/""))) --iFail; 

And again, while I'd APPRECIATE an insight into what silly mistake I've made, it would make my day to have a utility that would show me the error of my ways, by simply plugging in my macro.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

夜唯美灬不弃 2024-09-12 14:32:00

输入图像描述此处转至https://godbolt.org/。在左窗格中输入代码,然后选择编译器作为 gcc,将参数设置为右窗格中的 -E。您的预处理代码将显示在右侧。

enter image description hereGo to https://godbolt.org/. Enter your code in the left pane and select compiler as gcc put the argument as -E in the right pane. Your pre-processed code will appear on the right.

蓦然回首 2024-09-12 14:32:00

您只需通过预处理器运行您的代码,它将显示它将被扩展成什么(或根据需要吐出错误):

$ cat a.c
#define GETADDR_FOR(a) if (!(a = (#_#a)GetProcAddress(h, "/""#a"/""))) 
GETADDR_FOR(hexdump)

$ gcc -E a.c
# 1 "a.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "a.c"
a.c:1:36: error: '#' is not followed by a macro parameter

GETADDR_FOR(hexdump)

在 GCC 中,gcc -E foo.c 仅预处理文件。

Visual Studio 使用 /P 参数。

You can just run your code through the preprocessor, which will show you what it will be expanded into (or spit out errors as necessary):

$ cat a.c
#define GETADDR_FOR(a) if (!(a = (#_#a)GetProcAddress(h, "/""#a"/""))) 
GETADDR_FOR(hexdump)

$ gcc -E a.c
# 1 "a.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "a.c"
a.c:1:36: error: '#' is not followed by a macro parameter

GETADDR_FOR(hexdump)

In GCC, it's gcc -E foo.c to only preprocess the file.

Visual Studio uses the /P argument.

生寂 2024-09-12 14:32:00

您似乎对 C 预处理器宏中字符串化或标记粘贴的确切语法感到困惑。

您可能会发现此页面关于C 预处理器宏通常很有帮助。

特别是,我认为这个宏应该这样读:

#define GETADDR_FOR(a) if (!(a = (_##a)GetProcAddress(h, #a))) --iFail

应该跳过尾随的 ; ,因为您可能会将其键入为 GETADDR_FOR(hexdump);,如果您不这样做它在你的 C 代码中看起来不会很奇怪并且会混淆许多语法荧光笔。

正如其他人提到的,gcc -E 将运行预处理器并跳过其他编译步骤。这对于调试预处理器问题很有用。

You appear to be confused about what the exact syntax is for stringifying or token pasting in C preprocessor macros.

You might find this page about C preprocessor macros in general helpful.

In particular, I think this macro should read like this:

#define GETADDR_FOR(a) if (!(a = (_##a)GetProcAddress(h, #a))) --iFail

The trailing ; should be skipped because you will likely be typing this as GETADDR_FOR(hexdump);, and if you don't it will look very strange in your C code and confuse many syntax highlighters.

And as someone else mentioned gcc -E will run the preprocessor and skip the other compilation steps. This is useful for debugging preprocessor problems.

迷路的信 2024-09-12 14:32:00

您可能想看看 Boost Wave 。与大多数 Boost 一样,它实际上更像是一个库,而不是一个实用程序,但它确实有一个驱动程序可以充当完整的预处理器。

You might want to take a look at Boost Wave. Like most of Boost, it's really more a library than a utility, but it does have a driver to act as a complete preprocessor.

缺⑴份安定 2024-09-12 14:32:00

任何基于 Clangd 的 IDE 都可以扩展宏,例如带有 Clangd 插件的 VSCode(而不是普通的 C/C+ 插件)。

将光标置于宏上,CtrlShiftEnter -> “扩展宏”。

Any Clangd-based IDE can expand macros, e.g. VSCode with the Clangd plugin (instead of the stock C/C+ one).

Position your cursor onto the macro, CtrlShiftEnter -> 'expand macro'.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文