Git Product home page Git Product logo

csbindgen's People

Contributors

cloone8 avatar danielmelody avatar dependabot[bot] avatar dsmiller95 avatar gamedolphin avatar github-actions[bot] avatar guitarrapc avatar hadashia avatar higumachan avatar kevaundray avatar koolieaid avatar mayuki avatar neuecc avatar nicholasmaselli avatar nihohit avatar oovm avatar pcysl5edgo avatar sewer56 avatar skgland avatar startewho avatar xanathar avatar xpl0itr avatar yamachu avatar

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

csbindgen's Issues

Cannot handle the struct when the type hierarchy is too deep.

I've installed libpng via vcpkg.

The problem is that struct png_row_info_struct, which bindgen did generate, is not generated by csbindgen.

The following source code is about as much as we can reproduce the problem.

build.rs

use std::error::Error;

fn main() -> Result<(), Box<dyn Error>> {
    // bindgen::Builder::default()
    //     .header("C:/src/vcpkg/installed/x64-windows/include/libpng16/png.h")
    //     .header("C:/src/vcpkg/installed/x64-windows/include/libpng16/pngconf.h")
    //     .header("C:/src/vcpkg/installed/x64-windows/include/libpng16/pnglibconf.h")
    //     .generate()
    //     .unwrap()
    //     .write_to_file("src/libpng16.rs")
    //     .unwrap();

    csbindgen::Builder::new()
        .input_bindgen_file("src/libpng16.rs")
        //.method_filter(|x| x.starts_with("png_"))
        .csharp_namespace("PixivApi.ImageFile")
        .csharp_class_name("LibPng16")
        .csharp_dll_name("libpng16")
        .generate_csharp_file("../src/PixivApi.ImageFile/libpng16_csbindgen.cs")?;

    Ok(())
}

The result files gist

C# Action

Hi,

We currently have to write static callback to get a future response from a Rust function. Example:

unsafe
{
    [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvCdecl) })]
    static void MyCallback()
    {
        // Ok callback
    }

    [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvCdecl) })]
    static void MyErrorCallback(byte* cString)
    {
        // Error callback
    }

      NativeMethods.fn(
          &MyCallback,
          &MyErrorCallback
      );
}

Would it be possible to use create Action this way so that we can stay in the same context:

unsafe
{
    var callback = () => 
    {
        // Ok callback
    };

    var errorCallback = (byte* cString) =>
    {
        // Error callback
    };

    NativeMethods.fn(
        &callback,
        &errorCallback
    );
}

failed to run custom build command

error: failed to run custom build command for rust_to_cs v0.1.0 (/Users/anton/CLionProjects/rust_to_cs)

Caused by:
process didn't exit successfully: /Users/anton/CLionProjects/rust_to_cs/target/debug/build/rust_to_cs-6a3f9f0f0bafc3d7/build-script-build (exit status: 101)
--- stderr
thread 'main' panicked at 'input file not found, path: /src/lib.rs: Os { code: 2, kind: NotFound, message: "No such file or directory" }', /Users/anton/.cargo/registry/src/github.com-1ecc6299db9ec823/csbindgen-1.7.3/src/lib.rs:40:14
note: run with RUST_BACKTRACE=1 environment variable to display a backtrace

Build.rs
fn main() { csbindgen::Builder::default() .input_extern_file("/src/lib.rs") .csharp_dll_name("nativelib") .generate_csharp_file("/dotnet/NativeMethods.g.cs") .unwrap(); }

lib.rs
#[no_mangle] pub extern "C" fn my_add(x: i32, y: i32) -> i32 { x + y }

csbindgen generates unknown type "C"

Version

1.9.2

Issue

Given the following Rust enum:

#[repr(C)]
pub enum CResultStatus {
    Ok,
    Err,
}

Version 1.8.0 generated the following csharp enum:

    enum CResultStatus : uint
    {
        Ok,
        Err,
    }

whereas the new version generates:

    enum CResultStatus : C
    {
        Ok,
        Err,
    }

dotnet then throws an error due to it not knowing what type C is

C# DLL's Cannot Be Found With Readme Example

Hello! I just found the library today and I've been playing around with it. But I may have found a few issues with the readme example (I could also be doing something very silly but I've looked around for a while)

I have a very simple program.cs file:

using CsBindgen;

Console.WriteLine(NativeMethods.my_add(1, 2));

I have a build.rs that looks like this:

fn main() {
    csbindgen::Builder::default()
        .input_extern_file("src/lib.rs")
        .csharp_dll_name("nativelib")
        .generate_csharp_file("./dotnet/NativeMethods.g.cs")
        .unwrap();
}

with a src/lib.rs that looks like this:

// lib.rs, simple FFI code
#[no_mangle]
pub extern "C" fn my_add(x: i32, y: i32) -> i32 {
    x + y
}

And a Cargo.toml file that looks like this:

[package]
name = "test-blob"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]

[build-dependencies]
csbindgen = "1.7.2"

When I run the code I get the C# File NativeMethods.g.cs that looks like this:

// <auto-generated>
// This code is generated by csbindgen.
// DON'T CHANGE THIS DIRECTLY.
// </auto-generated>
#pragma warning disable CS8500
#pragma warning disable CS8981
using System;
using System.Runtime.InteropServices;

namespace CsBindgen
{
    internal static unsafe partial class NativeMethods
    {
        const string __DllName = "nativelib";

        [DllImport(__DllName, EntryPoint = "my_add", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
        public static extern int my_add(int x, int y);
    }
}
    

I've removed the "unsafe" keyword and change "internal" to "public" however, when I run dotnet run

I get this error

Hello, World!
Unhandled exception. System.DllNotFoundException: Unable to load DLL 'nativelib' or one of its dependencies: The specified module could not be found. (0x8007007E)
   at CsBindgen.NativeMethods.my_add(Int32 x, Int32 y)
   at Program.<Main>$(String[] args) in Program.cs:line 7

I've tried several methods of fixing this but it looks like the target folder from ``cargo build``` did not build the dll.

Do you know a way to fix this? This seems like a very silly error that I am making but I cannot seem to figure it out

Support configurable calling convention or infer it from function declaration?

Sorry for the messy text. I am trying to understand the historical layers here. Therefore, this is 60% question, 40% feature request.

I'll start with the fact that I am a bit confused about what calling convention actually is the default on which platform.

The Rust reference says something about the default here: https://doc.rust-lang.org/reference/items/external-blocks.html#abi. It says that cdecl is only the default on x86_32, but on x86_64 the default is win64, but on the forums it is said that extern "C" is whatever LLVM considers to be the default. LLVM docs say that the default "C" calling convention is indeed cdecl. https://llvm.org/doxygen/namespacellvm_1_1CallingConv.html

C#'s CallingConvention enum doesn't even have a field for win64, so I guess that calling convention isn't actually used much?

The question: Is cdecl really the default everywhere?


This said, it would be useful, if we could configure the calling convention for the generated bindings. What if we do extern "stdcall" fn in Rust? Currently, csbindgen doesn't pick it up.

Add an option to rename structs

Thanks for your cool project!

I was wondering if csbindgen could have a way to rename struct/enums/constants, similarly to cbindgen with [export.rename]?

Context

I am creating a Rust library that will be used by a C# program. Most of my library is implemented without FFI in mind, and sometimes I need to convert structs from my library to semantically equivalent data structures that I can share through FFI. For example:

struct Configuration {
  version: String
}

// ffi equivalent:
#[repr(C)]
struct Configuration {
  version: *const c_char
}

This works well, but I have a naming clash: both structures are called Configuration!

Ideally, I would like to keep using the original name in my lib, and use another name for the FFI version, for example:

struct Configuration {
  version: String
}

// ffi equivalent:
#[repr(C)]
struct FfiConfiguration {
  version: *const c_char
}

But when generating the C# file, I don't want those Ffi prefixes, I'd prefer to expose the original name.

This could maybe be implemented as a new csbindgen::Builder method, like so:

csbindgen::Builder::default()
  .rename("FfiConfiguration", "Configuration")

about ffmpeg

how to use the csbindgen to make the ffmpeg c# bind?

Support code inside module blocks

I have a use case which requires parsing code which may be inside module blocks.

Motivation

I want to support parsing macro expansions in my binding files, and I need macro expansions (at this point) only to support generic types.

The best way I found to support macro expansions is to run my code through cargo expand to a temporary file, then ingest that with the csbindgen tool to generate the bindings. However, cargo expand will always wrap code inside nested module blocks.

In short, I need cargo expand to support macros which I can use to provide generic-like support. and Cargo expand generates code similar to the following example:

Minimal example:

src/lib.rs:

pub mod interop_module{
    #[no_mangle]
    pub extern "C" fn triple_input(input: i32) -> i32 {
        input * 3
    }
}

build.rs:

fn main() {
    csbindgen::Builder::default()
        .input_extern_file("src/lib.rs")
        .generate_csharp_file("target/dotnet/SystemRuntimeRust.g.cs")
        .unwrap();
}

Expected output:

SystemRuntimeRust.g.cs:

//.. truncated usings
namespace CsBindgen
{
    internal static unsafe partial class NativeMethods
    {
        const string __DllName = "";

        [DllImport(__DllName, EntryPoint = "triple_input", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
        public static extern int triple_input(int input);
    }
}

Actual output:

SystemRuntimeRust.g.cs:

//.. truncated usings
namespace CsBindgen
{
    internal static unsafe partial class NativeMethods
    {
        const string __DllName = "";
    }
}

Omitting the module wrapper produces the expected output:

src/lib.rs:

#[no_mangle]
pub extern "C" fn triple_input(input: i32) -> i32 {
    input * 3
}

Proposed solution

For my use case I want all the nested modules to automatically unwrap into the same output class. This does have the potential to cause typename collisions, but I believe that can be categorized as user error and would be pretty quickly obvious as a problem. I'm going to try to implement this in my fork of the repo.

Suggest a more friendly way to generate

I want to export a complex structure, but its internal definition does not need to be exposed to Csharp, and all its' interface using csharp type.

https://github.com/Cysharp/csbindgen#pointer is what I need, but I want to have some better output.

The flow I want is roughly as follows:

Step1, Rust High Level

#[repr(C)]
pub struct CounterContext {
    set: HashSet<i32>,
}

#[cs_bindgen(Box)]  // or Rc, Arc, ...
// replace all self as Box<Self>, then can wrap by Box::into_raw and Box::from_raw
impl CounterContext {
    #[cs_bindgen(constructor)]
    pub fn create_counter_context() -> Self {
        Self {
            set: HashSet::new(),
        }
    }
    // value is a csharp type
    pub fn insert_counter_context(&mut self, value: i32) {
        self.set.insert(value);
    }
    #[cs_bindgen(destructor))]
    pub fn delete_counter_context(&mut self) {
        for value in self.set.iter() {
            println!("counter value: {}", value)
        }
    }
}

Step2, Rust Low Level

#[no_mangle]
pub extern "C" fn create_counter_context() -> *mut c_void {
    let ctx = Box::new(CounterContext {
        set: HashSet::new(),
    });
    Box::into_raw(ctx) as *mut c_void
}

#[no_mangle]
pub unsafe extern "C" fn insert_counter_context(context: *mut c_void, value: i32) {
    let mut counter = Box::from_raw(context as *mut CounterContext);
    counter.set.insert(value);
    Box::into_raw(counter);
}

#[no_mangle]
pub unsafe extern "C" fn delete_counter_context(context: *mut c_void) {
    let counter = Box::from_raw(context as *mut CounterContext);
    for value in counter.set.iter() {
        println!("counter value: {}", value)
    }
}

Step3, C# Low Level

    internal static unsafe partial class NativeMethods
    {
        const string __DllName = "nativelib";

        [DllImport(__DllName, EntryPoint = "create_counter_context", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
        public static extern void* create_counter_context();

        [DllImport(__DllName, EntryPoint = "insert_counter_context", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
        public static extern void insert_counter_context(void* context, int value);

        [DllImport(__DllName, EntryPoint = "delete_counter_context", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
        public static extern void delete_counter_context(void* context);

    }

Step4, C# High Level

    public class CounterContext
    {
        private void* _handle;
        public CounterContext()
        {
            _handle = NativeMethods.create_counter_context();
        }

        public void Insert(int value)
        {
            NativeMethods.insert_counter_context(_handle, value);
        }

        ~CounterContext()
        {
            NativeMethods.delete_counter_context(_handle);
        }
    }

This makes a more human-friendly experience.

Do not include `#[test]` functions

I create tests for bindings in the same file with bindings themselves (or else it gets me a lot of troubles with visibility). And these test functions are includuded in bindings for C# so maybe don't include functions with #[test] attribute? Or maybe even include only functions with #[no_mangle] attribute? I can make pull request if this feature is needed.

Renaming invalid field names such as 'delegate'

When we have a struct field with an invalid name in C# world, it causes compilation failure.

For example:

pub struct NfcCard {
    delegate: extern "C" fn(ByteArray) -> ByteArray,
}

This code is converted to:

[StructLayout(LayoutKind.Sequential)]
internal unsafe partial struct NfcCard
{
    public delegate* unmanaged[Cdecl]<ByteArray, ByteArray> delegate;
}

In this context, the name delegate is the reserved word in C#, so the compiler says:

error CS1519: Invalid token 'delegate' in class, record, struct, or interface member declaration

It would be great if csbindgen renames the reserved words of C# I think.

Test failed

Simply run cargo test cause following errors:

---- tests::update_package_version stdout ----
thread 'tests::update_package_version' panicked at 'index out of bounds: the len is 1 but the index is 1', csbindgen/src/lib.rs:185:12
note: run with RUST_BACKTRACE=1 environment variable to display a backtrace

---- tests::test stdout ----
starting dir: /Users/danielhu/Projects/csbindgen/csbindgen
thread 'tests::test' panicked at 'input file not found, path: csbindgen-tests/src/liblz4.rs: Os { code: 2, kind: NotFound, message: "No such file or directory" }', csbindgen/src/lib.rs:41:14

Somewhat confusing documentation on NuGet csbindgen

Hello, I am trying to understand what the NuGet csbindgen is used for as I am having troubles to understand this.

First of all, in Unity it would not be easy to install (nuGet is not supported there) but I am assuming this is just an utility (?). The whole CS bindings generation is done from Rust so I am a bit confused on why this is needed.

I tried to install such NuGet however from the IDE (which I know will be overwritten by Unity, but still it is to try it out) and I get:

Could not install package 'csbindgen 1.9.2'. You are trying to install this package into a project that targets '.NETFramework,Version=v4.7.1', but the package does not contain any assembly references or content files that are compatible with that framework. For more information, contact the package author.

However there is no clear dependency specified in csbindgen NuGet, so I am confused on why it does not work.

Can I solve this by simply adding the nuget code to my project somehow?

`*const char` should be translated `*uint`

Hi, thanks for this awesome crate :)

I think *const char should be translate to *const uint.

  • In the 0.1.2 I was getting *char but I don't think this is acurate because sizeof(char) == 2 so the aligment might be also off
  • In the 1.4.0 I'm getting a *@char not sure what is happening

Support generating bindings from dependent crates

Can csbindgen look at a crates's dependencies when generating bindings? Let's imagine

Crate dll:

pub use api_types::Vec2;

fn function(x: *const Vec2) {}

Crate types:

#[repr(C)]
pub struct Vec2 {
    pub x: f32,
    pub y: f32,
}

Currently it looks like it doesn't search dependencies for types to output. If we run csbindgen in dll/build.rs, it won't include types defined in types.

Wrong translation of fielded enum/not refusing to do so

#[repr(u8)]
pub enum FieldedEnum{
    A(u8),
    B(i8),
}
std::mem::size_of::<FieldedEnum>() -> 2

currently this gets translated as

public enum FieldedEnum : byte
{
  A,
  B
}

which is wrong in length

i am not sure if this is stabilized, but if the length of each field is the same i guess it may even now be considered okay to use.
https://doc.rust-lang.org/nomicon/other-reprs.html

i would suggest implementation like this:

using System;
using System.Runtime.InteropServices;

[StructLayout(LayoutKind.Sequential)]
public struct MyData
{
	public enum Variant : byte
	{
		A,
		B
	}

	[StructLayout(LayoutKind.Explicit)]
	private struct Union
	{
		[FieldOffset(0)]
		internal byte A;

		[FieldOffset(0)]
		internal sbyte B;
	}
    public Variant Type { get; private set; }
    private Union data;

    public byte A
    {
        get
        {
            if (Type != Variant.A)
                throw new InvalidOperationException($"{nameof(MyData)} is not of variant {nameof(Variant.A)}, but {this}");
            return data.A;
        }
        set
        {
            Type = Variant.A;
            data = new Union {A = value}; //must be done with with to make sure all other fields are zeroed out
        }
    }

    public sbyte B
    {
        get
        {
            if (Type != Variant.B)
                throw new InvalidOperationException($"{nameof(MyData)} is not of variant {nameof(Variant.B)}, but {this}");
            return data.B;
        }
        set
        {
            Type = Variant.B;
            data = new Union {B = value};
        }
    }
	
	public override string ToString()
	{
		switch (Type)
		{
			case Variant.A:
				return $"{nameof(MyData)}.{nameof(Variant.A)}: {A}";
			case Variant.B:
				return $"{nameof(MyData)}.{nameof(Variant.B)}: {B}";
			default:
				throw new InvalidOperationException("Invalid variant of {nameof(MyData)}!");
		}
	}

}

https://dotnetfiddle.net/PDCeTO

Support constants?

If there is a constant in the Rust file, it is not does not appear in the generated bindings.

pub const THINGY_CREATE_FLAGS__OPTIMIZE: u32 = 1 << 0;

For instance cbindgen makes this a #define, if you target C.

#define THINGY_CREATE_FLAGS__OPTIMIZE (1 << 0)

Build using input_bindgen_file() isn't generating FFI code

I don't use Rust, so I'm not sure if I'm just setting up the files incorrectly, but I'm trying to take existing Rust code and call the functions from within C#.

I setup a submodule for the existing repo and then made a rslib-bridge folder to hold the csbindgen code.
Here are my files:

Cargo.toml

[package]
name = "rslib-bridge"
version = "0.1.0"
edition = "2021"

[lib]
crate-type = ["cdylib"]

[dependencies]

[build-dependencies]
csbindgen = "1.8.0"

build.rs

fn main() {
    csbindgen::Builder::default()
        .input_bindgen_file("../anki/rslib/src/decks/service.rs")
        .rust_file_header("use super::service::*;")
        .csharp_entry_point_prefix("csbindgen_")
        .csharp_dll_name("service")
        .generate_to_file("service_ffi.rs", "../dotnet/NativeMethods.service.g.cs")
        .unwrap();
}

This is the existing Rust file that I'm trying to generate from.
When I run cargo build, I get the generated service_ffi.rs file, but it doesn't contain any of the function calls.

service_ffi.rs

/* automatically generated by csbindgen */

#[allow(unused)]
use ::std::os::raw::*;

use super::service::*;


    

I thought maybe it was because the service.rs file I'm pulling from uses impl and has all the functions nested in it, instead of having them at the base level. So I deleted the generated files and tried again but this time using the default generated lib.rs file (with the test deleted) and got the same result.

src/lib.rs

pub fn add(left: usize, right: usize) -> usize {
    left + right
}

build.rs

fn main() {
    csbindgen::Builder::default()
        .input_bindgen_file("src/lib.rs")
        .rust_file_header("use super::service::*;")
        .csharp_entry_point_prefix("csbindgen_")
        .csharp_dll_name("service")
        .generate_to_file("service_ffi.rs", "../dotnet/NativeMethods.service.g.cs")
        .unwrap();
}

Can't get struct bindings unless in the same file

Hi I am going crazy because something that seemed to be working doesn't really work anymore and I have no idea why.

I have a file:
src/classes/counter.rs
and its ffi:
src/ffi/counter_ffi.rs

I only run csbindgen on counter_ffi.rs and until last week it was also generating the empty structs for Counter and Args. But right now I cannot get it. I do not really know why and would need help, since this might be an issue.

Content of counter.rs:

#[repr(C)]
pub struct Args {
    pub  init: u32,
    pub  by: u32,
}

#[repr(C)]
pub struct Counter {
    val: u32,
    by: u32,
}

impl Counter {
    pub fn new(args: Args) -> Counter {
        Counter{
            val: args.init,
            by: args.by,
        }
    }

    pub fn get(&self) -> u32 {
        self.val
    }

    pub fn incr(&mut self) -> u32 {
        self.val += self.by;
        self.val
    }

    pub fn decr(&mut self) -> u32 {
        self.val -= self.by;
        self.val
    }
}

Content of counter_ffi.rs:

use std::mem::transmute;
use crate::classes::counter::{Args, Counter};

#[no_mangle]
pub extern fn counterCreate(args: Args) -> *mut Counter {
    let _counter = unsafe { transmute(Box::new(Counter::new(args))) };
    _counter
}

#[no_mangle]
pub extern fn counterGetValue(ptr: *mut Counter) -> u32 {
    let mut _counter = unsafe { &mut *ptr };
    _counter.get()
}

The resulting .cs file DOES NOT contain the Counter struct, so the code is unusable. But I swear that it worked until now and I got the empty Counter struct there.

CS file:

    internal static unsafe partial class CounterUnsafeFFI
    {
        [DllImport(__DllName, EntryPoint = "counterCreate", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
        public static extern Counter* counterCreate(Args args);

        [DllImport(__DllName, EntryPoint = "counterGetValue", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
        public static extern uint counterGetValue(Counter* ptr);
    }

What am I missing? Really the counter_ffi.rs should be in the exact same file of the counter.rs?

GroupingExtensionMethods fails to strip type name from function name

I am using csbindgen version 1.8.3.

// GroupedNativeMethods.cs
using GroupedNativeMethodsGenerator;

namespace Bindings;

[GroupedNativeMethods]
internal static unsafe partial class Libsql{}

Here's one example of a generated extension method.

// Bindings.Libsql.GroupedNativeMethods.g.cs
...
public static bool RowsIteratorNext(this ref global::Bindings.RowsIterator @rows_iterator)
{
    return Libsql.rows_iterator_next((global::Bindings.RowsIterator*)Unsafe.AsPointer(ref @rows_iterator));
}
...

According to the documentation, I'd expect RowsIterator to be stripped and to have the extension method simply be Next. Am I missing something obvious? Thanks.

I can't find the library specified in `.csharp_dll_name`.

My expectation was that running cargo build --release would generate libzsd and reference it from C#.
The build.rs also has the following description.

csbindgen::Builder::new()
    .input_bindgen_file("src/zstd.rs")
    .method_filter(|x| x.starts_with("ZSTD_"))
    .rust_file_header("use super::zstd::*;")
    .csharp_class_name("LibZstd")
    .csharp_dll_name("libzsd")
    .generate_to_file("src/zstd_ffi.rs", ". /dotnet-sandbox/zstd_bindgen.cs")? ;

But I couldn't find libzsd. The zstd_bindgen.cs is generated without any problem.
I can't find the library specified in .csharp_dll_name.

Sorry if my work is wrong.

environment

  • macOS Monterey v12.6.8
  • Apple M1 Pro
  • csbindgen v1.8.3
  • rustc 1.73.0 (cc66ad468 2023-10-03)

How to generate struct when i not have a .rs file?

I defined a struct in a crate:

   #[repr(C)]
   pub struct ByteVecPtr {
     pub ptr: *const u8,
     pub len: usize,
   }

How to generate this struct to csharp when i dependency the struct . I can't find the .rs file when dependence on crate.io.

   #[no_mangle]
    pub extern "C" fn ads_read_motor_para_l(byte_vec_ptr:ByteVecPtr) -> bool {
         return true;
     }

About document generation

Existing documentation generation seems to simply add summary?

It does not convert rustdoc markdown syntax to C# doc syntax.

How about remove the summary, and I can directly write xml-style C# documents?

initial release TODO

  • rewrite rust emitter
  • collect extern(out) rust method
  • builder API
  • method filter
  • C# method name entrypoint
  • configurable emitter
  • GitHub Action
  • ReadMe
  • Add vendor.yml (ignore c dir)
  • More generate check
    • ZStandard
    • quiche
    • bullet physics
  • Upload to crates.io

can not handling *mut *const

for example b3

  B3_SHARED_API void b3GetUserDataInfo(b3PhysicsClientHandle physClient, int bodyUniqueId, int userDataIndex, const char** keyOut, int* userDataIdOut, int* linkIndexOut, int* visualShapeIndexOut);

const char** keyOut -> *mut *const keyOut

Library loading for every known RIDs

I have to admit that this is not up to you to propose this but it is really sad that the .NET SDK doesn't offer a built-in way to retrieve native libraries. Or even providing a proper example on how to load native libraries.

Anyway, there is already a great solution in the readme that can work with win|osx|linux OS and x86|x64|arm64 process architectures. However, it does not cover the full list of RIDs, or at least the most commonly used you can find here: https://learn.microsoft.com/en-us/dotnet/core/rid-catalog#known-rids

The current implementation is sufficient to cover Windows and OSX platforms. However, I do not find a way to cover Android and iOS platforms. And same for deduping musl vs. non-musl.

Did you encounter this issue and have you found a solution?

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.