Code Monkey home page Code Monkey logo

ffi-convert-rs's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ffi-convert-rs's Issues

Missing CReprOf impls for u8 and i8

The code here seems to be a weirdly incomplete list of types, missing u8, i8 and isize in various places. isize might be tricky I guess but u8 is pretty annoying because it means I can't use Vec<u8> which is surely really common?

This is the error you get with Vec<u8>:

error[E0277]: the trait bound `u8: CReprOf<u8>` is not satisfied
  --> src\lib.rs:19:10
   |
19 | #[derive(CReprOf, AsRust, CDrop)]
   |          ^^^^^^^ the trait `CReprOf<u8>` is not implemented for `u8`
   |
   = help: the following implementations were found:
             <u8 as CReprOf<bool>>
   = note: required because of the requirements on the impl of `CReprOf<Vec<u8>>` for `CArray<u8>`
   = note: required by `c_repr_of`

Unfortunately this is impossible to fix in my code because u8 and CReprOf aren't defined by me.

How to convert from c struct efficiently

This crate looks like a good candidate for doing C# <--> Rust ffi through a C API. I will be passing C structs to C# from rust, and then sending those C structs back to rust.

My concern is that I see no way to convert the c struct back to the rust struct efficiently, as AsRust doesn't take ownership of the C struct. I'm assuming this was done intentionally, but I'm struggling to see why. Is there any way that I can avoid for example deep copying the CArray? I don't think we can even dereference it right now on the rust side without cloning the data into a Vec

Fix: documentation example

Dear ffi convert team,

I think this example in the docs

#[repr(C)]
pub struct CPizza {
    pub name: *const libc::c_char,
    pub toppings: *const CArray<CTopping>,
    pub base: *const CSauce,
    pub weight: libc::c_float,
}

should be?

#[repr(C)]
pub struct CPizza {
    pub name: *const libc::c_char,
    pub toppings: *const CArray<CTopping>,
    #[nullable]
    pub base: *const CSauce,
    pub weight: libc::c_float,
}

Add conversion for fixed size arrays

Hello,

Could it be possible to add conversion for fixed size arrays ?
Like:
pub struct Dummy {
a: [u8;4],
b: [i32;12],
...
}

I've created a rust struct generator (using IDL representation format) that create a "pure" rust struct and the repr(C) equivalent.
This coupled with cbindgen and ffi-convert (that are key piece off the whole system, thank you !) allow me to generate a complete "chain" of data exchange C<-->Rust.

Sadly, ffi-convert lacks a feature for me, the fixed array conversion. I want to let the user of my lib create a IDL representing a specific C ABI message (for example a messaging to talk to an external device through serial/udp/tcp...) and let them use (from C) a driver (i created in Rust, on top of udp socket/serial/tcp socket...) that take and return the repr(C) struct corresponding the the IDL struct.

Since the serialization/deserialization can't be done with serde/bincode (because bincode insert the vec length in addition of the inner data) i have to use Bytemuck. But bytemuck only works with Copy types ---> fixed size arrays.

Examples in 'ffi-convert/lib.rs' are a little unclear

The examples at the start of ffi-convert/lib.rs are a little unclear because they hide some uses and structs, notably for ffi_convert::CArray which makes it harder to discover ffi-convert by simply copying the examples and going from there.

The section Caveats with derivation of CReprOf and AsRust traits is also empty, which made me think the published version was not up-to-date with HEAD.

CStringArray derive [CReprOf, CDrop] error

Hello,

I'm encountering issue when deriving CreprOf and CDrop on a struct that have a field of type '*const CStringArray'
Like this:

#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct TestStringArray {
    s: Vec<String>,
}

#[derive(Debug, CReprOf, AsRust, CDrop, RawPointerConverter, Clone)]
#[repr(C)]
#[target_type(TestStringArray)]
pub struct TestStringArray_t {
    s: *const CStringArray,
}

#[no_mangle]
pub extern "C" fn nodus__msg__TestStringArray_t__create(s: *const CStringArray) -> *mut c_void {
    let s = unsafe { CStringArray::as_rust(&*s as &CStringArray).unwrap() };

    let msg = TestStringArray { s };
    let msg = TestStringArray_t::c_repr_of(msg).unwrap();
    Box::into_raw(Box::new(msg)) as *mut c_void
}

#[no_mangle]
pub extern "C" fn nodus__msg__TestStringArray_t__destroy(msg: *mut TestStringArray_t) -> () {
    let msg = unsafe { Box::from_raw(msg) };
}

I'm facing these issues:

error[E0599]: no method named `into_raw_pointer` found for struct `CStringArray` in the current scope
  --> nodus-bindings/src/generated/msgs/TestStringArray.rs:18:17
   |
18 | #[derive(Debug, CReprOf, AsRust, CDrop, RawPointerConverter, Clone)]
   |                 ^^^^^^^ method not found in `CStringArray`
   |
   = note: this error originates in the derive macro `CReprOf` (in Nightly builds, run with -Z macro-backtrace for more info)
help: one of the expressions' fields has a method of the same name
   |
18 | #[derive(Debug, size.CReprOf, AsRust, CDrop, RawPointerConverter, Clone)]
   |                 +++++

error[E0599]: no function or associated item named `drop_raw_pointer` found for struct `CStringArray` in the current scope
  --> nodus-bindings/src/generated/msgs/TestStringArray.rs:18:34
   |
18 | #[derive(Debug, CReprOf, AsRust, CDrop, RawPointerConverter, Clone)]
   |                                  ^^^^^ function or associated item not found in `CStringArray`
   |
   = note: this error originates in the derive macro `CDrop` (in Nightly builds, run with -Z macro-backtrace for more info)

For more information about this error, try `rustc --explain E0599`.
error: could not compile `nodus-bindings` due to 2 previous errors

What am i doing wrong ? Could be bug ?

Size in CArray is int32_t?

Just discovered this - looks like exactly what I need. I was just a bit confused by this note in the docs:

typedef struct {
const T *values; // Pointer to the value of the list
int32_t size; // Number of T values in the list
} CArrayT;

Shouldn't the type of size be size_t? Or at least uint32_t?

Btw the link to the docs in the readme doesn't go to the latest version.

Make CArray 'Clone'

Hello,

I need CArray to be clone for my 'Message's structures to be Clone as well.

I'm using a dependency that return a reference to a 'Message' when i do a read. The 'Message's struct are behind a generic type M that have a bound Clone on it.
I can use 'to_owned()' on &M to have a M, thanks to the Clone bound.

Is it possible for you to modify CArray to be Clone please ?

The other possibility for me is to require '&self' instead of 'self' in the 'c_repr_of(...)' function.
But the 'Clone' way is less restricting.

Converting opaque pointer

Is it possible to convert between structs and opaque pointers. I want to convert a rust struct that contains a opaque pointer.

I am new to rust so please forgive me if the approach was silly:

  • I tried it by declaring the rust struct with fields and the c struct empty. But that didn't worked.
  • Than i tried using libc::c_void by impl the CReprOf and AsRust but it is not posible to implement foreign traint to foreign type.

CArray cannot exposed well to C with cbindgen

Hello,

First, is will explain my global application purpose:
I'm generating Rust struct and Rust struct repr(C) from IDL files. I've crated the parser (with Pest) and the dumper (with Tera).
The structures i generate are using this crate.
I need the users to be able to crate their IDLs, and do nothing else than compile to genereate new FFI header and .so where all the structures repr(C) i generated are exposed with cbindgen.

Sad point however, the complex types like CArray are not exposed correctly, it's exposed like:

typedef struct MyStructure_t {
  unsigned char var1;
  const struct Type1_t *var2;
  const CArray<unsigned char> *var3;
  const CArray<short> *var4;
  const CArray<unsigned char> *var5;
  const CArray<short> *var6;
} MyStructure_t;

IDL:

#include "Type1.idl";

struct MyStructure {
    @key octet var1;
    Type1 var2;
    octet var3[9];
    short var4[9];
    sequence<octet> var5;
    sequence<short> var6;
};

File generated from previous IDL:

use std::ffi::*;
use ffi_convert::{AsRust, AsRustError, CArray, CDrop, CReprOf, CReprOfError, RawBorrow, RawPointerConverter};
use serde::{Deserialize, Serialize};
use rustdds::Keyed;

use super::{Type1::Type1,Type1_t};
#[derive(Debug, Serialize, Deserialize)]
pub struct MyStructure {
    var1: u8,
    var2: Type1,
    var3: Vec<u8>,
    var4: Vec<i16>,
    var5: Vec<u8>,
    var6: Vec<i16>,
}

impl MyStructure {
    pub fn to_c(self) -> Result<MyStructure_t, CReprOfError> {
        let c = MyStructure_t::c_repr_of(self);
        c
    }
}


impl Keyed for MyStructure {
    type K = u8;

    fn key(&self) -> Self::K {
        self.var1
    }
}
#[allow(non_camel_case_types)]
#[derive(Debug, CReprOf, AsRust, CDrop, RawPointerConverter)]
#[repr(C)]
#[target_type(MyStructure)]
pub struct MyStructure_t {
    var1: c_uchar,
    var2: *const Type1_t,
    var3: *const CArray<c_uchar>,
    var4: *const CArray<c_short>,
    var5: *const CArray<c_uchar>,
    var6: *const CArray<c_short>,
}

impl MyStructure_t {
    pub fn to_rust(&self) -> Result<MyStructure, AsRustError> {
        let pure = self.as_rust();
        pure
    }
}

How did you do to expose those kind of complex type to C through cbindgen please ?

cbindgen not creating the right headers for ffi-convert-rs structs

Dear ffi convert team,

I am learning go, rust and the interactions between these 2 languages by consuming rust methods by golang.

I have done some tests and I am getting error in cgo trying to understand the header files generated by dbindgen...

This is my rust code

use ffi_convert::RawBorrow;
use ffi_convert::{AsRust, CArray, CDrop, CReprOf, CStringArray, RawPointerConverter};
use futures::executor::block_on;
use mesa::hsm::group::r#struct::{HsmGroup, Member};
use std::ffi::{c_char, c_float, c_int, c_schar, c_uchar, c_uint, CStr};

#[derive(CReprOf, AsRust, CDrop, RawPointerConverter, Debug)]
#[target_type(Member)]
pub struct CMember {
    #[nullable]
    ids: *const CStringArray,
}

#[repr(C)]
#[derive(CReprOf, AsRust, CDrop, RawPointerConverter, Debug)]
#[target_type(HsmGroup)]
pub struct CHsmGroup {
    label: *const libc::c_char,
    #[nullable]
    description: *const libc::c_char,
    #[nullable]
    members: *const CMember,
    #[nullable]
    exclusive_group: *const libc::c_char,
    #[nullable]
    tags: *const CStringArray,
}

#[no_mangle]
pub extern "C" fn get_hsm_group(
    data: CHsmGroup,
) {
 // do something
}

This is my build.rd for dbindgen

extern crate cbindgen;

use std::env;

fn main() {
    let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap();

    cbindgen::Builder::new()
        .with_crate(crate_dir)
        .generate()
        .expect("Unable to generate bindings")
        .write_to_file("bindings.h");
}

And this is the headers file generated

#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>

typedef struct CMember CMember;

typedef struct CHsmGroup {
  const char *label;
  const char *description;
  const struct CMember *members;
  const char *exclusive_group;
  const CStringArray *tags;
} CHsmGroup;

void get_hsm_group(struct CHsmGroup data);

I know very little but I think the below may not right?

typedef struct CMember CMember;

I would expect something like below?

typedef struct CMember {
  const char *const *ids;
} CMember;

typedef struct CHsmGroup {
  const char *label;
  const char *description;
  const struct CMember *members;
  const char *exclusive_group;
  const char *const *tags;
} CHsmGroup;

I crated an example here https://github.com/Masber/rust-ffi this creates a shared library that I am using in a Go code, the header file is automatically generated by cbindgen during the build process cargo build --release

How to work `CStringArray` C type?

Dear ffi convert team,

I am learning go, rust and the interactions between these 2 languages by consuming rust methods by golang/cgo.

This is my rust code

use ffi_convert::RawBorrow;
use ffi_convert::{AsRust, CArray, CDrop, CReprOf, CStringArray, RawPointerConverter};
use futures::executor::block_on;
use mesa::hsm::group::r#struct::{HsmGroup, Member};
use std::ffi::{c_char, c_float, c_int, c_schar, c_uchar, c_uint, CStr};

#[repr(C)]
#[derive(CReprOf, AsRust, CDrop, RawPointerConverter, Debug)]
#[target_type(Member)]
pub struct CMember {
    #[nullable]
    ids: *const CStringArray,
}

#[repr(C)]
#[derive(CReprOf, AsRust, CDrop, RawPointerConverter, Debug)]
#[target_type(HsmGroup)]
pub struct CHsmGroup {
    label: *const libc::c_char,
    #[nullable]
    description: *const libc::c_char,
    #[nullable]
    members: *const CMember,
    #[nullable]
    exclusive_group: *const libc::c_char,
    #[nullable]
    tags: *const CStringArray,
}

#[no_mangle]
pub extern "C" fn get_hsm_group(
    data: CHsmGroup,
) {
 // do something
}

This is my build.rd for dbindgen

extern crate cbindgen;

use std::env;

fn main() {
    let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap();

    cbindgen::Builder::new()
        .with_crate(crate_dir)
        .generate()
        .expect("Unable to generate bindings")
        .write_to_file("bindings.h");
}

And this is the headers file generated

#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>

typedef struct CMember {
  const CStringArray *ids;
} CMember;

typedef struct CHsmGroup {
  const char *label;
  const char *description;
  const struct CMember *members;
  const char *exclusive_group;
  const CStringArray *tags;
} CHsmGroup;

void get_hsm_group(struct CHsmGroup data);

My understanding is that CStringArray is not part of the C standard library.

My question is:

How should I use CStringArray? do I need to import a library in C to use it?

Thank you very much

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.