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

      

  • 相关阅读:
    Lotus Notes中文档查询(转)
    MSSQL日志管理
    VS使用带临时表的存储过程
    TaskbarForm
    IT人士在离职后可以做的14件事情
    app.config数据库连接字符串的加密
    IT职场人,切不要一辈子靠技术生存
    wmi资料
    迁移成功
    【SpeC#】-C#的又一同胞兄弟
  • 原文地址:https://www.cnblogs.com/leemano/p/14733475.html
Copyright © 2011-2022 走看看