C回调函数在未命名的命名空间中定义? [英] C callback functions defined in an unnamed namespace?

查看:247
本文介绍了C回调函数在未命名的命名空间中定义?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a C++ project that uses a C bison parser. The C parser uses a struct of function pointers to call functions that create proper AST nodes when productions are reduced by bison:

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

现在,在项目的C ++部分,我填写这些指针

Now, in the C++ part of the project, i fill those pointers

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代码调用by-name,所以名称调整不是一个问题。使它们被破坏将避免名称冲突,因为一些动作被称为错误,并且C ++回调函数具有类似下面的丑陋的名称,以避免与其他模块的名称冲突。

Now the only reason i put them within extern "C" is because i want them to have C calling conventions. But optimally, i would like their names still be mangled. They are never called by-name from C code, so name mangling isn't an issue. Having them mangled will avoid name conflicts, since some actions are called like error, and the C++ callback function has ugly names like the following just to avoid name clashes with other modules.

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

  /* ... */
}

a.error = &uglyNameError;

我想知道是否可以通过只给出函数类型C链接

I wondered whether it could be possible by merely giving the function type C linkage

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

任何想法?我在寻找Standard-C ++解决方案。

Any ideas? I'm looking for Standard-C++ solutions.

推荐答案

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

I don't get the problem. The extern keyword does not affect the calling convention, merely the name presented to the linker. A function written in C++ that is not an instance method is still __cdecl, with or without extern "C". Furthermore, as long as you keep createActions() in the same source code file, these functions don't need external linkage. You could declare them static or put them in an unnamed namespace to avoid collisions.

这篇关于C回调函数在未命名的命名空间中定义?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆