我有一个使用 C 野牛解析器的 C++ 项目。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++ 解决方案。