Pregunta

Tengo un proyecto de C ++ que utiliza un analizador C bisonte. El analizador C utiliza una estructura de punteros de función para llamar a funciones que crean nodos AST adecuadas cuando producciones se reducen por el bisonte:

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

Ahora, en el C ++ parte del proyecto, i llenar esos punteros

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;
}

Ahora, la única razón por la que los puse dentro extern "C" es porque yo quiero que tengan convenciones de llamada C. Sin embargo, de manera óptima, me gustaría sus nombres todavía ser destrozados. Ellos nunca son llamados por el nombre de código C, por lo renombrado de nombres no es un problema. Tenerlos destrozados evitarán conflictos de nombre, ya que algunas acciones se denominan como error, y la función de devolución de llamada de C ++ tiene nombres feos como los siguientes sólo para evitar conflictos de nombres con otros módulos.

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

  /* ... */
}

a.error = &uglyNameError;

Me preguntaba si podría ser posible simplemente dando la vinculación tipo de función C

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

Algunas ideas? Estoy en busca de soluciones estándar-C ++.

¿Fue útil?

Solución

No entiendo el problema. La palabra clave extern no afecta a la convención de llamada, simplemente el nombre presentado al enlazador. Una función escrita en C ++ que no es un método de instancia es todavía __cdecl, con o sin extern "C". Por otra parte, siempre y cuando mantenga createActions () en el mismo archivo de código fuente, estas funciones no deben enlazado externo. Se podría declararlos estática o ponerlos en un espacio de nombres sin nombre a colisiones evitar.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top