2012-08-04 2 views
0

저는 주로 데이터베이스에 읽고 쓰는 C++ 래퍼가있는 Fortran 77로 구성된 프로그램을 가지고 있습니다. 응용 프로그램 공유의 두 부분은 Fortran 공통 블록과 같은 전역 C/C++ 구조체를 사용하는 기능을 사용합니다. 나는 C++/포트란 통합에 대한이 앨리어싱 접근법이 1) 많은 컴파일러 스위트에서 작동한다는 것을 확신한다. 2) * not8 표준이다. 가능한 한 표준 구성 요소를 사용하도록 코드를 유지하려고합니다. 또한,이 통합은 부서지기 쉬운 것으로 입증되었습니다. utd.h에서공통 블록에서 Fortran 및 C++ 혼합 언어 라이브러리를 다시 엔지니어링하는 방법 - 전역 구조체 앨리어싱?

:

/************************************************************* 
* This struct must follow the common block points. 
* See the Fortran include file points.i 
*************************************************************/ 
typedef struct ALIGN points 
{ 
    double point[3][MAX_PTS]; 
    double edge[3][MAX_PTS]; 
    double edgenorm[3][MAX_PTS]; 
    double edgerho[MAX_PTS]; 
    int  nfacets[MAX_PTS]; 
    double facet1[3][MAX_PTS]; 
    double facet2[3][MAX_PTS]; 
    double gaussk[MAX_PTS]; 
    int  sbstin[MAX_PTS]; 
    int  coatin[MAX_PTS]; 
    int  sbstout[MAX_PTS]; 
    int  coatout[MAX_PTS]; 
    int  ncorners[MAX_PTS]; 
    double cnrpoint[3][MAX_CNRS][MAX_PTS]; 
    int  ncnredgs[MAX_CNRS][MAX_PTS]; 
    double cnredge[3][MAX_CNREDS][MAX_CNRS][MAX_PTS]; 
    int  cnrsbst[MAX_CNREDS][MAX_CNRS][MAX_PTS]; 
    int  cnrcoat[MAX_CNREDS][MAX_CNRS][MAX_PTS]; 
    int  npoints; 
} POINTS; 

extern POINTS points_; 

utd.cpp에서 :

! maxpnt - maximum number of points in a path. 
    integer maxpnt 
    parameter (maxpnt = 1000) 

    integer npoints, nfacets(maxpnt) 
    integer ncorners(maxpnt), ncnredgs(maxpnt,maxcorners) 
    integer sbstin(maxpnt), coatin(maxpnt) 
    integer sbstout(maxpnt), coatout(maxpnt) 
    double precision point(maxpnt,3) 
    double precision edge(maxpnt,3), edgenorm(maxpnt,3) 
    double precision edgerho(maxpnt) 
    double precision facet1(maxpnt,3), facet2(maxpnt,3) 
    double precision gaussk(maxpnt), cnrpoint(maxpnt,maxcorners,3) 
    double precision cnredge(maxpnt,maxcorners,maxcnredges,3) 
    integer cnrsbst(maxpnt,maxcorners,maxcnredges) 
    integer cnrcoat(maxpnt,maxcorners,maxcnredges) 

    common /points/ point, edge, edgenorm, edgerho, 
*    nfacets, facet1, facet2, gaussk, 
*    sbstin, coatin, sbstout, coatout, 
*    ncorners, cnrpoint, ncnredgs, 
*    cnredge, cnrsbst, cnrcoat, 
*    npoints 

더 나은 방법이 있나요 : points.i에서

POINTS points_; 

? 공통 블록을 모듈로 변환하고 싶습니다. 그렇다면 글로벌 구조체를 가진 공통 블록을 앨리어싱하는이 사업이 창 밖이라고 확신합니다. C++에서 Fortran 모듈을 구성하는 방법은 무엇입니까? 어떻게 그러한 모듈에서 데이터를 읽습니까?

C++/Fortran 통합에 대한 조언은 무엇입니까?

+0

당신의 목적에 맞는 것이라면 Dunno를 선택하십시오. 그러나 저에게있어 마음에 떠오르는 점은 spec 파일을 읽고 C++ 및 fortran 코드를 자동 생성하는 전처리 단계입니다. 빌드 프로세스의 일부로 C++ 및 Fortran 파일을 더 이상 동기화되지 않게 만들 수 있습니다. –

답변

5

Fortran 2003의 ISO C 바인딩은 C 및 Fortran과 Fortran 언어 표준의 상호 운용성을 제공하므로 컴파일러와 플랫폼을 이식 할 수 있습니다. C의 기능 만 사용하는 경우 C++에서 작동 할 가능성이 높습니다.하지만 절대적으로 보장되지는 않습니다. 소스 파일 내에서 또는 두 언어 버전으로 작성된 루틴을 혼합하여 Fortran 2003과 FORTRAN 77을 혼합 할 수 있습니다. ISO C 바인딩은 구조 및 모듈 변수를 전역 변수로 지원하므로 목표를 달성 할 수 있습니다. 이 두 가지 모두 gfortran 매뉴얼의 혼합 언어 프로그래밍 장에 나와 있습니다. (ISO C 바인딩은 gfortran에만 국한되지 않습니다. 좋은 문서로 인용하고 있습니다.)

공용 블록도 지원되지만, 나는 여러분과 동의합니다. 공통 블록은 FORTRAN 저장 시퀀스에 추가됩니다. 및 레이아웃이 필요하지 않습니다. C와 Fortran "구조체"를 동등한 선언으로 수동으로 유지하는 방법은 없습니다. 이것이 취성의 이유 인 경우에는 조심해야합니다 (일반 지침에서 모두 작성하는 프로그램 작성 금지). 변수를 구조체에 두지 않는 것이 한 가지 접근법 일 것입니다 ... 새로운 변수를 잘못 받아들이면 이전 변수에 영향을 미치지 않으며 실수를 쉽게 알거나 디버깅 할 수 있습니다.

+0

'ISO_C_BINDING'을 사용하면 C++ 함수에서'extern "C"'가 필요합니까? gfortran 혼합 언어 문서를 살펴 보겠습니다. 나는이 프로젝트를 10 년 전에 시작했을 때 내가 오래된 Fortran77ish 버전을 보았다고 생각한다. – emsr

관련 문제