在未命名命名空间中定义的C回调函数? 我有一个C++项目,它使用了C BISY解析器。C解析器使用函数指针的结构调用函数,这些函数在bison减少生成时创建适当的AST节点: typedef void Node; struct Actions { Node *(*newIntLit)(int val); Node *(*newAsgnExpr)(Node *left, Node *right); /* ... */ }; 现在,在项目的C++部分,我填写这些指针< /p> 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; }

在未命名命名空间中定义的C回调函数? 我有一个C++项目,它使用了C BISY解析器。C解析器使用函数指针的结构调用函数,这些函数在bison减少生成时创建适当的AST节点: typedef void Node; struct Actions { Node *(*newIntLit)(int val); Node *(*newAsgnExpr)(Node *left, Node *right); /* ... */ }; 现在,在项目的C++部分,我填写这些指针< /p> 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; },c++,calling-convention,linkage,C++,Calling Convention,Linkage,现在我把它们放在extern“C”中的唯一原因是我希望它们有C调用约定。但最理想的情况是,我希望他们的名字仍然被弄乱。从C代码中从来没有按名称调用它们,所以名称损坏不是问题。因为它们被称为“代码>错误”,C++的回调函数有如下难看的名称,以避免与其他模块的名称冲突。p> extern "C" { void uglyNameError(char const *str) { /* ... */ } /* ... */ } a.error = &uglyNameErro

现在我把它们放在
extern“C”
中的唯一原因是我希望它们有C调用约定。但最理想的情况是,我希望他们的名字仍然被弄乱。从C代码中从来没有按名称调用它们,所以名称损坏不是问题。因为它们被称为“代码>错误”,C++的回调函数有如下难看的名称,以避免与其他模块的名称冲突。p>
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++编写的不是实例方法的函数仍然是*CCDL,有或没有外部“C”。此外,只要将createActions()保存在同一源代码文件中,这些函数就不需要外部链接。您可以将它们声明为静态的,或者将它们放在一个未命名的命名空间中,以避免冲突。

Ah,我可以将它们设置为
static
。好主意,为什么我没有想到:)我只想到了未命名的名称空间,但这不会对它们的链接产生任何影响,也不会防止
extern“C”
函数发生冲突。但是
static
实际上可以工作!对于您答案的其余部分:如果实现希望这样做,它可以改变调用约定。我不想依赖任何特定的实现,所以我让他们“代码>外部”C”/代码>。难道你不能把BISY输出编译成C++代码,这样就完全避免了问题吗?我的同事KONRAD说BISEN C++模式不好用,所以我们用纯C来做那个部分,并把它抽象化,所以和扫描器一起组成了一个纯C库。