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

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

Строка 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 и передачи ее функции, которую я не могу изменить, но Я не знаю, как это сделать. Любая помощь?

2 ответа

Решение

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

Я бы сделал еще одну оболочку Фортрана, которая бы 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 может быть ненужным, потому что двоичное представление такое же, просто попробуйте.

Другие вопросы по тегам