Как создать интерфейс для преобразования массива символов c для фортрана

Я пишу модуль на c для программы на фортране, и мне нужно передать некоторые строки в программу на фортране. Я не могу изменить код на Фортране, но могу написать свой собственный код на Фортране для вызова существующего кода. Я пытался погуглить это, и есть много разных подходов, написанных на уровне, который я не понимаю.

Строка c имеет переменную длину (хотя она устанавливается перед передачей). «Строка» фортрана объявлена ​​как символ * (*), поэтому я не вижу длины, до которой должен быть дополнен массив символов. Вот несколько фрагментов кода, чтобы увидеть, что мне нужно сделать.

c функция, которую я пишу:

void c_func(int db_handle) {
  char *geom_name;
  int geom_handle = 0;

  size_t geom_name_len = db_get_len(db_handle); !gets the length of the name
  geom_name = (char *)malloc(sizeof(char*(geom_name_len+1)));
  db_pull(db_handle, geom_name); !pulls geom_name from db as a null terminated string
  call_fortan_function(geom_handle, geom_name); !The fortran function will set the integer
  ...}

функция fortran, которую я не могу изменить, делает что-то с именем, а затем устанавливает значение для дескриптора:

logical function f_fn(handle, name)

integer handle
character*(*) name

Я предполагаю, что лучший способ сделать это - создать отдельную функцию c, которая анализирует geom_name на некоторые вещи, которые будет использовать fortran, а затем функцию fortran для создания строки fortran и передачи ее функции, которую я не могу изменить, но Я не знаю, как это сделать. Любая помощь?


person William Everett    schedule 26.09.2013    source источник


Ответы (2)


Вы не можете переносимо вызывать процедуру Fortran, требующую character(*) из C. Это невозможно, потому что процедура обычно принимает другой аргумент, определяющий длину строки. Вы можете попытаться угадать его формат, вероятно, это дополнительный int в качестве последнего аргумента.

Я бы сделал еще одну оболочку Fortran, которая принимала бы int с длиной и массив символов длиной length, желательно без завершающего \0.

logical function f_wrap(handle, name, length) bind(C,name="f_wrap")
  use iso_c_binding
  integer(c_int),value :: handle
  integer(c_int),value :: length
  character(1,kind=c_char),intent(in) :: name(length)
  character(length) :: tmp

  tmp = name
  f_wrap = f_fn(int(handle), tmp)
end function

tmp может быть ненужным, потому что двоичное представление такое же, просто попробуйте.

person Vladimir F    schedule 26.09.2013

Как вы думаете, эта страница может вам помочь? http://software.intel.com/sites/products/documentation/hpc/composerxe/en-us/2011Update/fortran/lin/bldaps_for/common/bldaps_hndl_charstr.htm

person superk    schedule 29.09.2013