zoukankan      html  css  js  c++  java
  • C# 调用 Rust 编写的 dll 之四:string

    C# 调用 Rust 编写的 dll 之四:string

    文中所有的程序运行环境为:windows 10 64bit,Net 5.0,Rust 1.51;乌龙哈里 2021-05-06

    C# 调用 Rust 编写的 dll 系列:

    1. 《C# 调用 Rust 编写的 dll 之一:创建 dll》
    2. 《C# 调用 Rust 编写的 dll 之二:输入输出简单数值》
    3. 《C# 调用 Rust 编写的 dll 之三:传递和修改数组》

    Rust中的 str 是 utf8 编码的 u8 数组,我们按这个原则来传递字符串。

    1、输入字符串:

    接上面系列的程序,rust lib.rs 添加

    #[no_mangle]//不写这个会把函数名编译成其他乱七八糟的
    pub extern fn input_str(ptr:*const u8,len:usize){
        let str=unsafe{
            let slice=std::slice::from_raw_parts(ptr, len);
            std::str::from_utf8(slice)
        };
        println!("Rust Dll get string: {}",str.unwrap());
    }

    c# 调用:

    using System.Text;//Encoding 要引用这个

    [DllImport("D:\LabRust\Learn\ln_dll\target\release\rustdll.dll", EntryPoint = "input_str", CallingConvention = CallingConvention.Cdecl)] public static extern void InputStr(byte[] arr, uint len); static void TestInputStr(string s) { //var data = Encoding.UTF8.GetBytes(s + ""; //转成 结尾的以utf编码的 u8 数组 var data = Encoding.UTF8.GetBytes(s); //已经指定大小了,没必要再以结尾 InputStr(data, (uint)data.Length); } static void Main(string[] args) { string s = "abcde"; TestInputStr(s); Console.WriteLine($"C# string: {s}"); Console.Read(); } /*输出结果: Rust Dll get string: abcde C# string: abcde */

    2、输出 string

    由于 [u8] 不是 FFI 安全的,所以要在 c# 里先设定 byte[] 的大小,然后在 rust dll 里面往输入的 byte[] 中添加字符串的内容。具体如下代码。

    #[no_mangle]//不写这个会把函数名编译成其他乱七八糟的
    pub extern fn output_str(ptr:*const u8,len:usize){
        let s="你好abcde";
        println!("Rust Dll output string: {}",s);
        let data=s.as_bytes();
        if data.len()<len{
            unsafe{
                let p=ptr as *mut u8;//裸指针,很危险!
                for (i,&v) in data.iter().enumerate(){
                    p.add(i).write(v);
                }
                // for i in 0..data.len(){
                //     p.add(i).write(data[i]);
                // }
            }    
        }    
    }

    cargo build --release 后,用 c# 调用:

    using System.Linq;//下面用到 lambda
            [DllImport("D:\LabRust\Learn\ln_dll\target\release\rustdll.dll",
            EntryPoint = "output_str",
            CallingConvention = CallingConvention.Cdecl)]
            public static extern void OutputStr(byte[] arr, uint len);
            static string TestOutputStr()
            {
                byte[] buff = new byte[1024];//预先指定字符串长度
                OutputStr(buff, (uint)buff.Length);
                var data = buff.Where(x => x > 0).ToArray();
                return Encoding.UTF8.GetString(data);
            }
    
    
            static void Main(string[] args)
            {
                Console.WriteLine($"C# string: {TestOutputStr()}");
                Console.Read();
            }
    
    /* 输出结果:
    Rust Dll output string: 你好abcde
    C# string: 你好abcde
    */

      

  • 相关阅读:
    kali-linux镜像下载
    清除数据库所有表
    家庭医生项目进展
    2020年度发展规划的要点
    Sql Server数据类型
    window server2012R2激活
    C#介绍
    WebApi自动接口文档Swagger汉化和添加Token验证
    SQL Server 数据库内部版本号
    用户定义表类型
  • 原文地址:https://www.cnblogs.com/leemano/p/14733475.html
Copyright © 2011-2022 走看看