2

I am writing an iso_c_binding in Fortran to call a C-function with the below prototype

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

My question is how do I declare unsigned char **outputbuf, a pointer that is used inside the c-function to allocate output buffer, in this interface?

Also, what data type I should be using in Fortran as the real parameter to pass to this outputbuf parameter? should it be allocatable? (if it is allocated inside the c-function)?

I currently drafted this module, but haven't tested it (I doubt it will work).

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
2
  • At the least character pointer(c_ptr) isn't a Fortran thing. Could you revisit the Fortran block you drafted to be more syntactically correct in what you think is appropriate? Commented May 25, 2020 at 0:17
  • Yes, I know that wasn't valid, just a place holder. Googled but only find examples of pointers, but not pointer of pointer. Commented May 25, 2020 at 2:19

1 Answer 1

1

Try type (C_PTR), intent (out). Then you will need to use Fortran function c_f_pointer to associate the C pointer with a Fortran pointer. Probably of type C_CHAR.

Sign up to request clarification or add additional context in comments.

5 Comments

Thank you, it works! here is the interface declaration, and here is my test code. However, the only remaining question is how do I "free" the myout pointer on the fortran side? valgrind detects a memory leak in this test code.
another follow-up question - is there any risk of using fortran native types vs iso_c_binding c-types? for example, for c_size_t, I used a integer(kind=8) on the fortran side, does this cause any side effect? similarly for character(kind=c_char) vs the native character type.
Re my earlier question on freeing the c-allocated buffer, I added a c-function to call free, and added it to the interface. github.com/fangq/zmat/blob/master/fortran90/…
The risk of not using the kind values declared in ISO_C_BINDING is that the compiler's kind values may not match C's. Why not use C_SIZE_T? kind=8 is inherently non-portable.
As you did, since the memory was allocated on the C side, it is best to free the memory on the C side. You can optionally nullify the Fortran pointer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.