我已经阅读了几种结合C和C ++代码的方法,但是,我仍然对如何处理我的情况感到困惑。这是我的问题:
我有相对大量的C代码(由各种组成 .c
和 .h
文件)用于模拟有限元和离散元素中的实体。这段代码具有相对简短的主要功能 for
循环,其中顺序调用各种其他函数(来自其他文件)。在Unix(icc编译器)和Visual Studio中编译时,此代码工作正常。
我在C ++中有其他代码可以解决分子动力学相互作用。此代码还包含各种文件,并在Unix(icpc编译器)和VS中运行良好。两者都是独立程序,具有自己的输入和输出文件集。
我需要做什么 是以我的C程序在其主循环中“调用”C ++代码的方式运行这两个程序。一些信息需要在两个代码之间双向传递,这两个代码可以是数组(或指针)的形式。
最简单的方法是什么?
特别是,根据我读过的建议,我有多个问题:
- 我应该用我的C头文件包装
extern "C" {}
? - 我应该用吗?
extern "C"
在我的C函数? - 或者我应该使用
extern "C"
在我的C ++文件中? (标题?函数?所有这些?还是只需要从C程序调用的那些?) - 在理解我不能有两个
main
功能。我可以简单地重命名我的C ++main
功能? - 在unix中编译时,我是否应该将C(icc)和C ++(icpc)编译器用于不同的文件?还是只是C ++编译器?
- 它可以是一个选项(简化事情)转换我的
main
从C到C ++的功能? - 如果我不需要在两个程序之间传递类的信息,我是否需要对它们做任何事情?
- 您建议以什么顺序解决此问题? (例如,首先让我的C程序由C ++编译器编译;第二,将两个代码编译在一起,没有链接;第三,链接代码;第四,重命名
main
在C ++中,我的C代码“调用”它;五,实施信息传递?) - 最后,每个程序中都有一些宏,它们是重复的(同名,相同的实现)。与此有冲突吗?我应该只保留一组宏吗?
抱歉,长文和多个问题。我对C相对较新,甚至比C ++更新,所以即使我对这些程序的词汇量有限。
谢谢您的帮助。任何提示将不胜感激。如果您需要其他信息,请告诉我。
这是我的C代码的“主要”功能:
#include "Yproto.h"
void show_time_info(YDC ydc,CHR Ystage[3]);
main(argc, argv)
INT argc; char **argv;
{ CHR c1name[300]; /* name of the problem i.e. input file */
struct YD_struct yd; /* Y database */
YDC ydc=&(yd.ydc); /* Y control database */
YDE yde=&(yd.yde); /* Y element database */
YDI ydi=&(yd.ydi); /* Y interaction database */
YDN ydn=&(yd.ydn); /* Y node database */
YDB ydb=&(yd.ydb); /* Y borehole database */
YDS yds=&(yd.yds); /* Y source (inter. fluid) database */
YDO ydo=&(yd.ydo); /* Y output database */
YDPE ydpe=&(yd.ydpe); /* Y property database for elements */
YDPN ydpn=&(yd.ydpn); /* Y property database for nodes (BC) */
YDPJ ydpj=&(yd.ydpj); /* Y property database for joints */
YDPM ydpm=&(yd.ydpm); /* Y property database for meshing */
INT Tctrlc, itimes=0;
CHR *p=NULL;
/* get name of the problem */
if(argv[1]!=NULL)
{ CHRcpy(c1name,argv[1]);
}
else
{ CHRwcr(stdout);
CHRw(stdout," please define input file names: "); CHRwcr(stdout);
CHRw(stdout," >");
fgets(c1name,sizeof(c1name),stdin);
if((p=strrchr(c1name,'\n'))!=NULL) *p = '\0';
}
strcpy(ydc->cfiname, c1name); ydc->cfiname[255]='\0';
ydc->finp=FILENULL; ydc->fcheck=FILENULL;
/* Process while any input */
while(Yrd(c1name,&yd)>0)
{ itimes=itimes+1;
CHRw(stdout,"NEW INPUT: "); CHRw(stdout, c1name); CHRwcr(stdout);
if(Ycheck(&yd)<0) break; date_and_time(ydc->cruntime); timestamp();
CHRw(stdout, "Start calculating ...\n");
omp_set_num_threads(8);
for(ydc->ncstep=ydc->ncstep;ydc->ncstep<ydc->mcstep;ydc->ncstep++)
{ show_time_info(ydc,"Ymd"); /* show time information */
Ymd(ydc,yde,ydi,ydn,ydpe,ydpn,ydpm); /* mesh elements */
/********** HERE IS WHERE I WOULD LIKE TO CALL MY C++ PROGRAM ***************/
Yfd(ydc,yde,ydn,ydi,ydo,ydpe,ydpn,ydpj); /* nodal forces */
Ybor(ydc,yde,ydn,ydb,yds,ydpe,ydpj,ydpn); /* borholes, inter. fluid */
Ycd(ydc,yde,ydi,ydn,ydpe,ydpn); /* contact detection */
Yid(ydc,yde,ydi,ydn,ydo,ydpe,ydpn, ydpj,ydpm); /* interaction */
Yod(c1name,&yd); /* output results */
Ysd(ydc,yde,ydn,ydo,ydpe,ydpn ); /* solve equations */
Yfrd(ydc,yde,ydi,ydn,ydpe,ydpn,ydpj,ydpm); /* fracture */
ydc->dctime=ydc->dctime+ydc->dcstec; /* update time */
/* CTRL-C Interruption */
Tctrlc = enablc(ydc->dctime, ydc->ncstep, ydc->mcstep);
if(Tctrlc!=1) break;
}
}
/* Termination */
CHRw(stderr," ***** Y HAS ORDERLY FINISHED *****"); CHRwcr(stderr);
CHRw(stderr,"Press a key to continue"); CHRwcr(stderr);
getchar();
}
回答后24小时更新
我按照提供的答案按照建议进行操作,我的问题的解决方案比原先想象的要简单得多(尽管在开始工作之前我确实需要探索几个选项)。最好的部分是它适用于Unix和Visual Studio。以下是我采取的步骤摘要:
将我的主C文件转换为C ++。为此,重命名包含该文件的文件
main
我的C代码的函数扩展名为.cpp(从Y.c更改为Y.cpp)并更改了开头main
功能来自:main(argc, argv) INT argc; char **argv;
至
int main(int argc,char **argv)
为了使C ++'友好'。 (注意:我知道将文件重命名为.cpp并不重要,但我认为为了清晰起见,最好这样做)。
用我的所有C头文件换行
#ifdef __cplusplus extern "C" { #endif
在开始时,和
#ifdef __cplusplus } #endif
最后。
改变我的名字
main
C ++函数和(暂时)不使用参数。我把它命名了int Ynano()
。创建一个名为Y_NANO.h的新头文件(Y_NANO.cpp是包含最初主要C ++函数的文件的名称),其中包含以下行:
int Ynano();
在Y.cpp和Y_NANO.cpp中包含新标头:
#include "Y_NANO.h"
调用该功能
Ynano()
来自main
Y.cpp中的函数。要在Visual Studio中编译,只需将所有源文件放在同一文件夹中并创建一个新项目。在Unix中,我按照给出的步骤操作 这里。
这些步骤只会使程序一起运行,而不会在它们之间传递信息。要在程序之间传递信息,必须包含一些参数作为参数 Ynano()
,但这是另一个故事。
一些最终评论:
- 在不同的头文件中重复宏的问题似乎不是一个真正的问题,只要没有文件包含两个头文件(我不需要对此做任何事情)。
- 感谢所有提供答案的人。他们真的很有帮助。选择的答案是在完整性的基础上选出的,但其他答案也同样好。我希望这个帖子可以帮助其他人完成他们的工作,因为许多其他线程帮助我做同样的事情。