Hello everyone, I am trying to initialize a structure object of CPP inside the rust by passing struct object from Cpp to Rust by pointer .
This structure contains various kinds of fields including a function , function pointer etc.I am getting segmentation fault and the other values initialised in Rust are also garbage values at Cpp end.
Please check the following code and output.Let me know the correct approach.
//file: ffi.h
#pragma once
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef signed short int16_t;
typedef signed int int32_t;
typedef unsigned int uint32_t;
struct inner1{
int32_t a;
};
enum class dummyEnum {
variant1 = 0,
variant2 = variant1,
variant3 = 1,
variant4 = 2,
};
enum class AvailableSensorCapabilityType : uint64_t {
NONE = 0,
READ_SENSOR_SETTINGS = 1,
DEPTH_OUTPUT = 1 << 1,
CONSTRAINED_HIGH_SPEED_VIDEO = 1 << 2,
MONOCHROME = 1 << 3,
};
typedef void (*OnDestroy)(const dummyEnum enum1, void *cookie);
struct Info{
std::string name1;
std::string name2;
int32_t var1_i32 = 0;
int32_t arr1d[2] = {
0,
};
int32_t (*arr2d)[4]{};
bool bool_var1;
float f_var1[4];
uint8_t *us_char1{};
inner1 *struct1{};
void *cookie = nullptr;
void (*fn1)(Info &info1){};
OnDestroy onDestroy{};
const bool isSupport(const AvailableSensorCapabilityType type) const {
//some operation
return true;
};
int32_t var2_i32 = 0;
};
extern "C"
{
void call_to_rust(Info *Infovar);
}
//file: main.rs
use std::ffi::c_void;
use std::os::raw::c_uint;
use std::os::raw::c_float;
use std::os::raw::c_uchar;
#[repr(C)]
#[allow(non_camel_case_types)]
pub struct inner1{
pub a:i32,
}
#[repr(C)]
#[allow(non_camel_case_types)]
pub enum dummyEnum {
variant1 ,
variant2 ,
variant3 ,
variant4 ,
}
#[repr(C)]
#[allow(non_camel_case_types)]
pub enum AvailableSensorCapabilityType {
NONE = 0,
READ_SENSOR_SETTINGS = 1,
DEPTH_OUTPUT = 1 << 1,
CONSTRAINED_HIGH_SPEED_VIDEO = 1 << 2,
MONOCHROME = 1 << 3,
}
//typedef void (*OnDestroy)(const dummyEnum ennum1, void *cookie);
type fn1ptr=fn(&Info)->c_void;
type OnDestroyptr=fn(dummyEnum,*const c_void)->c_void;
type isSupportptr=fn(AvailableSensorCapabilityType)->c_void;
#[repr(C)]
#[allow(non_snake_case)]
pub struct Info{
pub name1:String,
pub name2:String,
pub var1_i32 :i32,
pub arr1d:[i32;2], // or can i use *const i32?
pub arr2d:*const [i32;4],
pub bool_var1:bool,
pub f_var1:[c_float;4],// or f32
pub us_char1:*const c_uchar,
pub istruct1:*const inner1,
pub cookie:*const c_void,
pub fn1:fn1ptr,
pub OnDestroy:OnDestroyptr,
pub isSupport:isSupportptr,
pub var2_i32:i32,
}
#[allow(dead_code)]
pub static ARRAY1:[[i32;4];4]=[
[1,2,3,4],
[5,6,7,8],
[9,10,11,12],
[13,14,15,16]
];
#[no_mangle]
pub extern "C" fn call_to_rust(info_var: &mut Info){
info_var.var1_i32=10;
info_var.var2_i32=20;
info_var.arr1d=[99,88];
info_var.arr2d=ARRAY1.as_ptr();
info_var.f_var1=[0.5,0.5,0.5,0.5];
println!("rust code execute successfully");
}
//file pass.cpp
#include<stdio.h>
#include<iostream>
#include "ffi.h"
using namespace std;
int main(){
Info Infovar;
cout<<"calling rust create"<<endl;
call_to_rust(&Infovar);
cout<<"returned to cpp"<<endl;
cout<<"value of var1_i32 is:"<<Infovar.var1_i32<<endl;
cout<<"value of var2_i32 is:"<<Infovar.var2_i32<<endl;
cout<<"value of arr1d[1] is:"<<Infovar.arr1d[1]<<endl;
cout<<"value of arr2d[1][3] is:"<<Infovar.arr2d[1][3]<<endl;
cout<<"value of f_var1[2] is:"<<Infovar.f_var1[2]<<endl;
return 0;
}
Output:
calling rust create
rust code execute successfully
returned to cpp
value of var1_i32 is:-595791868
value of var2_i32 is:0
value of arr1d[1] is:0
Segmentation fault (core dumped)
Desired Output:
calling rust create
rust code execute successfully
returned to cpp
value of var1_i32 is:10
value of var2_i32 is:20
value of arr1d[1] is:88
value of arr2d[1][3] is:8
value of f_var1[2] is:0.5