C функции обратного вызова определяется в пространстве имен без имени?

У меня есть проект 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++.

6
задан Johannes Schaub - litb 9 May 2010 в 10:52
поделиться

1 ответ

Я не понимаю проблемы. Ключевое слово extern не влияет на соглашение о вызовах, а только на имя, представленное компоновщику. Функция, написанная на C ++, которая не является методом экземпляра, по-прежнему __cdecl, с или без extern «C». Более того, пока вы сохраняете createActions () в одном и том же файле исходного кода, эти функции не нуждаются во внешней связи. Вы можете объявить их статическими или поместить в безымянное пространство имен, чтобы избежать коллизий.

3
ответ дан 17 December 2019 в 18:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: