Как создать интерфейс для преобразования массива символов переменного тока в фортран
Я пишу модуль в 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
может быть ненужным, потому что двоичное представление такое же, просто попробуйте.
Как вы думаете, эта страница может вам помочь? http://software.intel.com/sites/products/documentation/hpc/composerxe/en-us/2011Update/fortran/lin/bldaps_for/common/bldaps_hndl_charstr.htm