77次发布

0.14.25 2024年6月20日
0.14.24 2024年3月16日
0.14.23 2024年2月14日
0.14.20 2023年11月14日
0.5.2 2021年7月30日

#219 in FFI

Download history 39/week @ 2024-05-03 61/week @ 2024-05-10 109/week @ 2024-05-17 340/week @ 2024-05-24 27/week @ 2024-05-31 120/week @ 2024-06-07 317/week @ 2024-06-14 564/week @ 2024-06-21 158/week @ 2024-06-28 291/week @ 2024-07-05 220/week @ 2024-07-12 355/week @ 2024-07-19 227/week @ 2024-07-26 88/week @ 2024-08-02 76/week @ 2024-08-09 147/week @ 2024-08-16

609次每月下载
用于 edge-transformers

MIT 许可证

270KB
4.5K SLoC

Interoptopus生成C#绑定。

用法

假设您已经编写了一个包含您的FFI逻辑的crate,名为example_library_ffi,并希望生成C#绑定,请按照以下说明操作。

在您的库中

Interoptopus属性添加到您编写的库中,并定义一个列出您希望导出所有符号的库存函数。所有支持的结构概述可以在参考项目中找到。

use interoptopus::{ffi_function, ffi_type, Inventory, InventoryBuilder, function};

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

#[ffi_function]
#[no_mangle]
pub extern "C" fn my_function(input: Vec2) -> Vec2 {
    input
}

pub fn my_inventory() -> Inventory {
    InventoryBuilder::new()
        .register(function!(my_function))
        .inventory()
}

将这些添加到您的Cargo.toml中,以便可以找到属性和绑定生成器(将...替换为最新版本)

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

[dependencies]
interoptopus = "..."
interoptopus_backend_csharp = "..."

tests/bindings.rs中创建一个单元测试,当使用cargo test运行时将生成您的绑定。在实际项目中,您可能希望将此代码添加到另一个crate中

use interoptopus::util::NamespaceMappings;
use interoptopus::{Error, Interop};

#[test]
fn bindings_csharp() -> Result<(), Error> {
    use interoptopus_backend_csharp::{Config, Generator};
    use interoptopus_backend_csharp::overloads::{DotNet, Unity};

    let config = Config {
        dll_name: "example_library".to_string(),
        namespace_mappings: NamespaceMappings::new("My.Company"),
        ..Config::default()
    };

    Generator::new(config, example_library_ffi::my_inventory())
        .add_overload_writer(DotNet::new())
        //.add_overload_writer(Unity::new())
        .write_file("bindings/csharp/Interop.cs")?;

    Ok(())
}

现在运行cargo test

如果您有任何不清楚的地方,可以在GitHub上的示例中找到。

生成的输出

以下输出可能是此后端可能生成的。如果您想自定义某些内容,请查看Config结构。如果您真的不喜欢某些内容的生成方式,很容易创建自己的

using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using My.Company;

namespace My.Company
{
    public static partial class InteropClass
    {
        public const string NativeLib = "example_library";

        /// Function using the type.
        [DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "my_function")]
        public static extern Vec2 my_function(Vec2 input);
    }

    /// A simple type in our FFI layer.
    [Serializable]
    [StructLayout(LayoutKind.Sequential)]
    public partial struct Vec2
    {
        public float x;
        public float y;
    }
}

依赖项