• 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
    */

      

  • 相关阅读:
    windows 11下载地址
    ubuntu 安装无线网卡驱动
    修复因为安装openssl 1.0.0而导致使用ssh和scp产生警告信息
    vim下Java自动补全插件javacomplete
    mysql 配置多实例(mysqld_multi)
    nagios 整合 ganglia 设置邮件、短信报警
    Linux (ubuntu 10.10) 安装两个MySQL
    HDU 3269 P2P File Sharing System
    ubuntu 10.10 安装 sun java
    闲逛计算机系统(一):从HelloWorld说起
  • 原文地址:https://www.cnblogs.com/leemano/p/14733475.html
Copyright © 2020-2023  润新知