Как объявить указатель-указатель с помощью iso_c_binding?

Я пишу iso_c_binding в Фортране для вызова C-функции с прототипом ниже

int zmat_run(
    const size_t inputsize,
    unsigned char *inputstr, 
    size_t *outputsize, 
    unsigned char **outputbuf,
    const int zipid, 
    int *ret, 
    const int iscompress
);

Мой вопрос: как мне объявить unsigned char **outputbuf, указатель, который используется внутри c-функции для выделения буфера вывода в этом интерфейсе?

Кроме того, какой тип данных я должен использовать в Фортране в качестве реального параметра для передачи этому параметру outputbuf? он должен быть размещаемым? (если он размещен внутри c-функции)?

В настоящее время я составлял этот модуль, но не тестировал его (сомневаюсь, что он будет работать).

module zmatlib
  use iso_c_binding, only: c_char, c_size_t, c_ptr, C_NULL_CHAR
  interface
    integer(c_int) function zmat_run(inputsize, inputbuf, outputsize, outputbuf, zipid, ret, level) bind(C, name="zmat_run")
      use iso_c_binding
      integer(c_size_t), value :: inputsize
      integer(c_int), value :: zipid, level
      integer(c_size_t),  intent(out) :: outputsize
      integer(c_int),  intent(out) :: ret
      character(kind=c_char),  intent(in)  :: inputbuf(*)
      character pointer(c_ptr),intent(out) :: outputbuf
    end function zmat_run
  end interface
end module

person FangQ    schedule 24.05.2020    source источник
comment
По крайней мере, character pointer(c_ptr) не относится к Фортрану. Не могли бы вы еще раз вернуться к составленному вами блоку Fortran, чтобы он был более синтаксически правильным в том, что, по вашему мнению, является подходящим?   -  person francescalus    schedule 25.05.2020
comment
Да, я знаю, что это недействительно, просто заполнитель. Погуглил, но нашел только примеры указателей, но не указатель указателя.   -  person FangQ    schedule 25.05.2020


Ответы (1)


Попробуйте тип (C_PTR), намерение (выход). Затем вам нужно будет использовать функцию Fortran c_f_pointer, чтобы связать указатель C с указателем Fortran. Вероятно, типа C_CHAR.

person M. S. B.    schedule 25.05.2020
comment
Спасибо, это работает! вот объявление интерфейса, а здесь это мой тестовый код. Однако остается единственный вопрос: как освободить myout указатель на фортране? valgrind обнаруживает утечку памяти в этом тестовом коде. - person FangQ; 25.05.2020
comment
еще один дополнительный вопрос - есть ли риск использования собственных типов fortran против iso_c_binding c-типов? например, для c_size_t я использовал integer(kind=8) на стороне фортрана, вызывает ли это какой-либо побочный эффект? аналогично для character(kind=c_char) по сравнению с родным типом character. - person FangQ; 25.05.2020
comment
В ответ на свой предыдущий вопрос об освобождении буфера, выделенного c, я добавил c-функцию для вызова free и добавил ее в интерфейс. github.com/fangq/zmat/blob/master/ fortran90 / - person FangQ; 25.05.2020
comment
Риск неиспользования значений типа, объявленных в ISO_C_BINDING, заключается в том, что значения типа компилятора могут не совпадать с C. Почему бы не использовать C_SIZE_T? kind=8 по своей сути не переносится. - person Steve Lionel; 26.05.2020
comment
Как и вы, поскольку память была выделена на стороне C, лучше всего освободить память на стороне C. При желании вы можете обнулить указатель Fortran. - person M. S. B.; 26.05.2020