我有一个C++项目,它使用一个C BySon解析器。C解析器使用函数指针结构来调用函数,这些函数在bison减少生成时创建正确的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++解决方案。