我将一些用C ++编写的代码混合到用C语言编写的代码中(由lex / yacc生成)。
我有一个指针(指向C ++类的void指针),main
和parser()
内部(yacc生成的解析函数)可见。该指针位于解析器的.h中,如下所示。
我希望con
指向的对象具有全局范围,实际上,它具有全局范围的指针,我可以访问main中的类,如解析器函数,但是对象里面没有。我的意思是,我可以在解析器中工作并向其添加数据但是当它返回main时是空的,不是破坏而是空的。看起来像解析中的对象是另一个在main中。
我想在整个项目中只有一个对象。我怎么做的?
注意:我想只保留一个对象,所以我不想讨论复制构造函数(它可以工作并且已经过测试),我只是一个对象(类似于单例)。
================================= main.cpp =========== =============================
#include <stdio.h>
#include <stdlib.h>
#include "Context.h"
extern "C" {
#include "parser.h"
}
int main(int argc, char** argv) {
*stderr = *stdout;
con = new_Context();
yyin=fopen(argv[1],"rb");
ret = yyparse();
return ret;
}
================================ parser.h ============ ==============================
#ifndef PARSER
#define PARSER
#include <stdio.h>
#include <stdlib.h>
#include "C_Context.h"
// ================ updated ========================
#define LINKAGE extern
#ifdef __cplusplus
extern "C" {
#endif
LINKAGE C_Context *con;
#ifdef __cplusplus
}
#endif
// ================ updated ========================
extern FILE* yyin;
int yyparse();
#endif
===================================== parser.c ======= ===============================
// ================ updated ========================
#include "parser.h"
#ifdef __cplusplus
extern "C" {
#endif
C_Context *con;
#ifdef __cplusplus
}
#endif
// ================ updated ========================
#include "y.tab.c"
================================== C_Context.h(fragmrnt)======= ================
typedef void C_Context;
typedef void C_TypeGroup;
#ifdef __cplusplus
extern "C" {
#endif
// create a context and return the class as void pointer
C_Context * new_Context();
#ifdef __cplusplus
}
#endif
=================================== C_Context.cpp(片段)====== =========
#include "Context.h"
#include <iostream>
#define con (*((Context *)c_con))
using namespace std;
extern "C" {
C_Context * new_Context(){
C_Context* ret =0x0;
try{
ret = (C_Context*) new Context();
}catch(char * ex){
cerr<< "Runtime error:" << ex;
}
return ret;
}
}
更新
我用你疯狂的建议更新,仍然无法正常工作。完全相同的问题。我做错了什么?
更新2:
有人建议我更多地描述问题。我不确定我应该描述什么,但我会尝试。
我有一个类名上下文,其中所有对象都是实现解释所需的函数。该对象是具有地图/向量类的地图/向量的复杂anidations。一切顺利,解析,我的意思是,我可以通过包装器C_Context访问上下文类的所有功能。我的问题是语言应首先解析初始化文件然后解析脚本,因为对象必须在第一个初始化文件之后保留数据以便能够正确运行脚本。
当然还有其他方法,我可以制作一个临时文件,包含所有脚本和初始化文件。但是这种限制或难以使某种语言包含在内的可能性。如果我这样做,那么我必须先读取包含的文件并将所有文件添加到一个文件中,最后运行真正的解释。所以我更愿意能够多次运行解析器。为此,我需要保持相同的上下文。
我不知道这是否有帮助。
更新3
我申请的建议,据我所知,仍然是一样的。在parser()内的指针上添加元素,我可以使用它。但是当我回到main时再次是空的(没有破坏)。
(我检查一下语法和拼写法)
答案 0 :(得分:5)
在标头中声明变量extern
并在.c文件中定义它。否则每个翻译单元都有自己的定义。
更新:
看到你已经更新了你的代码,parser.c应该是这样的(以防编译器将.c文件编译为C ++):
// ================ updated ========================
#ifdef __cplusplus
extern "C" {
#endif
C_Context *con;
#ifdef __cplusplus
}
#endif
// ================ updated ========================
#include "y.tab.c"
您现在也可以extern "C" { ...
移除#include "parser.h"
。
答案 1 :(得分:0)
在标题中如下:
#ifndef myinclude_h
#define myinclude_h
#ifdef MAIN
int x;
#else
extern int x;
#endif
#endif
在这种情况下,您必须确保编译过程中的某个位置MAIN只在一个文件中定义。
或者如上所述的其他方式:
·H:
#ifndef myinclude_h
#define myinclude_h
extern int x;
#endif
的.cpp:
int x;
详细说明:
如果你想要一个全局变量,你可以在一些头文件中进行delcare,如上所示extern。这只是一个声明,它告诉编译器“某处”有一个名为x的int类型的变量。 您实际在一个c或cpp文件中声明了全局空间中的变量。手段,不是在类或类似的东西之内,而是在所有功能之外。例如,在main的顶部你可以在main来之前写它:
int x;
main()
{
}
无论你想要使用这个变量,都必须包含extern声明所在的头文件,然后你就可以访问它,就像任何其他变量一样。
在其他文件中:
#include "myinclude.h"
void fkt()
{
if(x < 10)
x+= 10;
cout << x << endl;
}
在你的主要:
#include <stdio.h>
#include <stdlib.h>
#include "Context.h"
#include "parser.h"
int main(int argc, char** argv) {
*stderr = *stdout;
con = new_Context();
yyin=fopen(argv[1],"rb");
ret = yyparse();
return ret;
}
你的parser.c中的
#ifdef __cplusplus
extern "C" {
#endif
C_Context *con;
#ifdef __cplusplus
}
#endif
应该这样做。
你的new_context()在哪里:
#include "parser.h"