gpt4 book ai didi

c++ - 在未命名的命名空间中定义的 C 回调函数?

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:42:09 24 4
gpt4 key购买 nike

我有一个使用 C bison 解析器的 C++ 项目。当产生式被 bison 减少时,C 解析器使用函数指针结构来调用创建正确 AST 节点的函数:

typedef void Node;
struct Actions {
Node *(*newIntLit)(int val);
Node *(*newAsgnExpr)(Node *left, Node *right);
/* ... */
};

现在,在项目的 C++ 部分,我填充那些指针

class AstNode {
/* ... */
};
class IntLit : public AstNode {
/* ... */
};

extern "C" {
Node *newIntLit(int val) {
return (Node*)new IntLit(val);
}

/* ... */
}

Actions createActions() {
Actions a;
a.newIntLit = &newIntLit;
/* ... */
return a;
}

现在我将它们放在 extern "C" 中的唯一原因是因为我希望它们具有 C 调用约定。但最理想的是,我希望他们的名字仍然被破坏。它们从不在 C 代码中按名称调用,因此名称修改不是问题。将它们打乱将避免名称冲突,因为某些操作的调用方式类似于 error,而 C++ 回调函数具有如下丑陋的名称,只是为了避免与其他模块发生名称冲突。

extern "C" {
void uglyNameError(char const *str) {
/* ... */
}

/* ... */
}

a.error = &uglyNameError;

我想知道是否可以仅通过给函数类型 C 链接来实现

extern "C" void fty(char const *str);
namespace {
fty error; /* Declared! But i can i define it with that type!? */
}

有什么想法吗?我正在寻找标准 C++ 解决方案。

最佳答案

我不明白这个问题。 extern 关键字不影响调用约定,仅影响提供给链接器的名称。用 C++ 编写的不是实例方法的函数仍然是 __cdecl,有或没有 extern "C"。此外,只要您将 createActions() 保留在同一个源代码文件中,这些函数就不需要外部链接。您可以将它们声明为静态的或将它们放在未命名的命名空间中以避免冲突。

关于c++ - 在未命名的命名空间中定义的 C 回调函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2797390/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com