我已经阅读了几种组合 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 扩展名(从 Yc 更改为 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()
,但那是另一回事了。
最后的一些评论:
- 在不同的头文件中重复宏的问题似乎不是一个真正的问题,只要没有文件包含两个头文件(我不需要对此做任何事情)。
- 感谢所有提供答案的人。他们真的很有帮助。选择的答案是在完整性的基础上选择的,但其他答案也一样好。我希望该线程可以帮助其他人完成他们的工作,因为许多其他线程也帮助我做同样的事情。