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!