Pass Rust Vectors to C STD_CALL

Hi!
I am currently trying to transfer parts of a project from Python to Rust. However, im having some trouble with the integration of a shared library which is originally programmed in Fortran and supposed to be called via C STDCALL.

In Python the library is called by the use of ctypes, converting all the arrays to string_buffers to hand them to the dll:

import ctypes as ct
trnDLL = ct.windll.LoadLibrary(self.dll_path)

def TRN_EOS(calctype,input,pr1,pr2,fluid, moles, eos_ind, mix_ind, path, unit):
	
		input_length = 12
		fluid_length = 30
		path_length = 255
		unit_length = 20
		
		# handle
		handle_ptr = ct.POINTER(ct.c_int)()

		# errorflag
        errorflag = ct.c_int(0)
		
		# input
		input = str.encode(input)
		input = ct.create_string_buffer(input.ljust(input_length),input_length)
		
		# calctype
        calctype = str.encode(calctype)
        calctype = ct.create_string_buffer(calctype.ljust(input_length),input_length)
		
		#fluid
        fluids_type = (ct.c_char * fluid_length) * fluid_length
        fluids_tmp = fluids_type()
        for i in range(0,fluid_length):
            fluids_tmp[i] = ct.create_string_buffer(b" ".ljust(fluid_length),fluid_length)
        for fid,fluid in enumerate(fluids):
            fluids_tmp[fid] = ct.create_string_buffer(str.encode(fluid.ljust(fluid_length)),fluid_length)
        	fluid = fluids_tmp
			
		#eos_ind
        eos_ind_tmp = (fluid_length * ct.c_int)()
        for eid,eos_id in enumerate(eos_ind):
            eos_ind_tmp[eid] =  eos_id
        eos_ind = eos_ind_tmp
		
		trnDLL = ct.windll.LoadLibrary(dll_path)

		TRN_EOS_STDCALL.restype = ct.c_double
		
        return trnDLL.TRN_EOS_STDCALL(calctype,
									  input,
									  ct.byref(ct.c_double(pr1)), 		 																				  ct.byref(ct.c_double(pr2)),
									  fluid,
									  moles,
									  eos_ind,
									  ct.byref(ct.c_int(mix_ind)),
									  str.encode(path),
									  str.encode(unit),
									  ct.byref(errorflag),
									  ct.byref(handle_ptr),
									  input_length,
									  input_length,
									  fluid_length,
									  path_length,
									  unit_length),
									  errorflag
# example call
result = TRN_EOS('D',
				 'PT',
				 9,
				 400,
				 ['fluid1', 'fluid2'],
				 [0.6, 0.4],
				 [1, 1],
				 12,
				 './dataFolder',
				 'molar',
				 )

Until im quite new to rust I still don't have a grasp how to correctly define the vectors and the pointer for the handle. My bindings.rs file actually looks like this:

extern "C" {
    pub fn TRN_EOS_STDCALL(
        Calctype: *const ::std::os::raw::c_char,
        Input: *const ::std::os::raw::c_char,
		Prop1: f64,
        Prop2: f64,
		Fluid: ??, // the input is an array of strings ["fluid1", "fluid2", ..]
        Moles: ??, // the input is an array of floats [0.6, 0.4, ..]
		Eos_ind: ??, // the input is an array of integers [1, 120, ..]
        Mix_ind: u32,
        Path: *const ::std::os::raw::c_char,
        Unit: *const ::std::os::raw::c_char,
        ErrFlag: i32,
        Handle: ??
    ) -> f64

However, the last posts in the forum have helped me only to a limited extent. (e.g. Pass a Vec from Rust to C - #10 by helix_tp)
Maybe anybody of you can give me some hints how to understand the whole thing a little better.
I am grateful for any help!

Please post the full signature of the function as it is in the C code.

Thanks for your reply.
The library is written in fortran so the STDCALL is defined like:

!double precision function TRN_EOS_STDCALL (calctype, input, pr1, pr2, fluid, moles, eos_ind, mix_ind, path, unit, errorflag, handle)
    !!DEC$ ATTRIBUTES DLLEXPORT, decorate, alias : "TRN_EOS_STDCALL" :: TRN_EOS_STDCALL
    !!DEC$ ATTRIBUTES stdcall, reference :: TRN_EOS_STDCALL
    !
    !
    !use, intrinsic :: iso_c_binding
    !use controlling
    !
    !implicit none
    !
    !!Handle for gl
    !type(c_ptr), intent(inout):: handle
    !
    !
    !!define input variables
    !character (12), intent(in) :: input
    !character(12), intent(in) :: calctype
    !character(20) :: unit
    !double precision, intent(in) :: pr1, pr2
    !character(30), dimension(30), intent(in) :: fluid
    !double precision, dimension (30), intent(in) :: moles
    !character (255), intent(in) :: path
    !integer, dimension (30), intent(in) :: eos_ind
    !integer, intent(in) :: mix_ind
    !integer :: errorflag
    !
    !double precision :: TRN_EOS
    !
    !
    !TRN_EOS_STDCALL = TRN_EOS (calctype, input, pr1, pr2, fluid, moles, eos_ind, mix_ind, path, unit, errorflag, handle)
    !
    !end function

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.