Символ прохода Fortran * 81 массив в код C / C ++

Я новичок в программировании, я хочу вызвать фортран-функцию в моем коде на С ++. Дело в том, что я не знаю, как передать массив символов Fortran * 81 в мой C ++.

Код Фортрана похож на:

subroutine func01(a)
implicit none
character*81 a(2)
write(*,*) a(1)
write(*,*) a(2)
end

C ++ код похож на:

#include <iostream>

extern "C"{
void func01_( const char **a );
}

int main()
{
const char *a[2];
a[0]="Hello world!";
a[1]="This is a test!";
func01_(a);
return 0;
}

Я протестировал мой код Fortran с помощью этого

program pro01
character*81 a(2)
a(1)='Hello world!'
a(2)='This is a test!'
call func01(a)
end program pro01

‘func01 (a)’ работает хорошо.

благодаря @PaulMcKenzie я исправил некоторые проблемы с дураками …..

Тем не менее, когда я скомпилировал код cpp, результат выглядел как грязный код:

 7
@L
@��n��@�UH�j��FP
@��n���U�շ�=��U�ྼ���   @��

что я должен делать?

0

Решение

Следующий код, кажется, работает для gcc4 в Linux (x86_64), но неясно, подходит ли он также для других платформ. (Как указывалось выше, C-совместимость современного Fortran может быть полезна.)

func01.f90

subroutine func01( a )
character(*) :: a( 2 )
print *
print *, "char length = ", len(a(1)), len(a(2))
print *, "raw a(1) : [", a(1), "]"print *, "raw a(2) : [", a(2), "]"print *, "trim     : [", trim(a(1)), "] [", trim(a(2)), "]"end

main.cpp

extern "C" {
void func01_( char *c, const int len );
}

#include <iostream>
#include <cstring>  // for memset()
int main()
{
const int lenmax = 30, numstr = 3; // changed char length to 30 to fit in the terminal
char a[ numstr ][ lenmax ];
std::string str[ numstr ];

str[0] = "moon"; str[1] = "mercury"; str[2] = "jupiter";

for( int k = 0; k < numstr; k++ ) {
memset( a[k], ' ', lenmax );  // fill space
str[k].copy( a[k], lenmax );  // copy at most lenmax char (no \0 attached)
}

func01_( a[0], lenmax );
func01_( a[1], lenmax ); // pass from mercury
return 0;
}

компилировать

$ g++ func01.f90 main.cpp -lgfortran

Результат

char length =           30          30
raw a(1) : [moon                          ]
raw a(2) : [mercury                       ]
trim     : [moon] [mercury]

char length =           30          30
raw a(1) : [mercury                       ]
raw a(2) : [jupiter                       ]
trim     : [mercury] [jupiter]
2

Другие решения

Вот переносимое решение для передачи массива строк произвольной длины из C в Fortran.

Я использовал файл C ++, очень похожий на ваш:

#include <iostream>

extern "C" void func01(const char **a);

int main()
{
const char *a[2] = {"Hello World","This is a test"};
func01(a);
return 0;
}

Единственными изменениями, приведенными выше, являются инициализация массивов символов и удаление не слишком переносимого подчеркивания функции Фортрана. Вместо этого мы будем использовать стандартную совместимость C, предоставляемую Fortran 2003. Реализация на Fortran func01 будет выглядеть так:

subroutine func01(cstrings) bind(C,name="func01")
use, intrinsic :: iso_c_binding, only: c_ptr, c_char, c_f_pointer
implicit none
type(c_ptr), dimension(2), target, intent(in) :: cstrings
character(kind=c_char), pointer :: a1(:), a2(:)

! size_t strlen(char * s);
interface
function strlen(s) bind(C, name='strlen')
use, intrinsic :: iso_c_binding, only: c_ptr, c_size_t
implicit none
type(c_ptr), intent(in), value :: s
integer(c_size_t) :: strlen
end function strlen
end interface

call c_f_pointer(cstrings(1), a1, [strlen(cstrings(1))])
call c_f_pointer(cstrings(2), a2, [strlen(cstrings(2))])
write (*,*) a1
write (*,*) a2
end subroutine func01

bind Атрибут — это то, что дает нам возможность взаимодействия с C для имени функции, и мы используем типы C для переменных. Переменная cstrings будет принимать массив из 2 указателей, или в C, *[2] или же **, Основная часть процедуры — это интерфейсный блок, который позволяет нам вызывать стандартную процедуру библиотеки C strlen чтобы сделать нашу жизнь проще с помощью следующих звонков c_f_pointer который переводит указатель C в указатель Fortran.

При компиляции и запуске, как и ожидалось, вывод будет:

$ ./string-array-test
Hello World
This is a test

Скомпилировано и протестировано с gcc 5.1.0.

2

По вопросам рекламы [email protected]