сделать с помощью компилятора g ++ / intel C ++, вызывая функции fortran - PullRequest
2 голосов
/ 22 апреля 2011

Я пытался вызвать некоторые функции из библиотеки, предоставленной коммерческим кодом конечных элементов. Примеры использования этой библиотеки компилируются с помощью компилятора intel fortran для моего типа системы, поэтому я использую компилятор intel c ++ для компоновки объектных файлов. Я установил простой тестовый пример с внешними объявлениями как

extern "C" 
{ 
  int binini_( int* );
  int biniqr8_( int*, int* ); 
  int binset_( int*, int*, int*, int*, int*, int*, const char*, int*, int*, int* );
  int binrd8_( int*, int*, int*, int*, int*, int* );
  int binclo_( int*, const char*, int* );
} 

А сейчас я пытаюсь использовать компилятор intel c ++ с указанным ниже make-файлом:

CXX = icpc -parallel  

IncludeDir = /home/utabak/external_libraries/boost_1_46_1

LinkingDir0 = /home/utabak/external_libraries/boost_1_46_1/stage/lib
LinkingDir1 = /opt/ansys-12.1/v121/ansys/customize/misc/linx64 
LibLink1 = bin
LibLink2 = boost_filesystem
LibLink3 = boost_system

all: test1

test1: test_binlib1.o  
  ${CXX} -o $@ $? -L${LinkingDir0} \
      -L${LinkingDir1} \
      -l${LibLink1} -l${LibLink2} -l${LibLink3}


test_binlib1.o: test_binlib1.cc
  ${CXX} -I${IncludeDir} -c $?

, который связывает и компилирует нормально. И беги как положено. Я хотел сделать то же самое с g ++ также, после некоторых проб и ошибок, я настроил make-файл, который прекрасно компилируется и компоновается:

CXX = g++ -g -pg -Wall -pthread

IncludeDir = /home/utabak/external_libraries/boost_1_46_1

LinkingDir0 = /home/utabak/external_libraries/boost_1_46_1/stage/lib
LinkingDir1 = /opt/ansys-12.1/v121/ansys/customize/misc/linx64 
LinkingDir2 = /home/utabak/intel/composerxe-2011/lib/intel64 

LibLink1 = bin
LibLink2 = boost_filesystem
LibLink3 = boost_system
LibLink4 = iomp5 # an extra library from intel compiler
                 # openmp, for intel C++ -parallel does it
                 # for g++ I have to explicitly link this

all: test1

test1: test_binlib1.o  
  ${CXX} ${LFLAGS} -o $@ $? -L${LinkingDir0} \
      -L${LinkingDir1} -L${LinkingDir2} \
      -l${LibLink1} -l${LibLink2} -l${LibLink3} -l${LibLink4}

test_binlib1.o: test_binlib1.cc
  ${CXX} -I${IncludeDir} -c $?

Однако этот исполняемый файл работает некорректно, и, как ни странно, иногда он дает ошибку сегментации или ошибку открытия файла, когда я сначала пытаюсь открыть файл с помощью вышеупомянутой библиотечной функции fortran binset_.

Я озадачиваюсь из-за этих ошибок и различий. Что может быть ответом на эту проблему?

1 Ответ

0 голосов
/ 29 апреля 2011

Я думаю, что вы можете быть пойманы струнами, которые вы передаете.При передаче строк между Fortran и C ++ вам необходимо учитывать скрытый аргумент длины.Прототипы, которые вы показываете для binset_ и binclo_, не включают это.

По умолчанию, когда Fortran передает аргументы, они все передаются по ссылке, за исключением скрытого аргумента длины строки, которая передается по значению.Этот скрытый аргумент длины добавляется в конец списка аргументов.

Рассмотрим процедуру Фортрана:

SUBROUTINE BLAH(MYSTRING)

Для стороны C ++ необходимо:

void blah_ (char *mystring, unsigned int mystringlength)
...