开启辅助访问 切换到宽版

精易论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

用微信号发送消息登录论坛

新人指南 邀请好友注册 - 我关注人的新帖 教你赚取精币 - 每日签到


求职/招聘- 论坛接单- 开发者大厅

论坛版规 总版规 - 建议/投诉 - 应聘版主 - 精华帖总集 积分说明 - 禁言标准 - 有奖举报

查看: 1374|回复: 15
收起左侧

[技术专题] RUST编写易语言可调用的dll

[复制链接]
结帖率:0% (0/1)
发表于 2023-7-1 22:29:28 | 显示全部楼层 |阅读模式   河北省邯郸市
本帖最后由 美稀宗 于 2023-7-2 17:48 编辑

-----------------------------------------20230702----------------------------------------
感谢@等等什么卿
给出了更快速的方案,大家可以参考原帖


https://bbs.125.la/thread-14787937-1-1.html


由于我没有得到原贴授权,这里就不贴源码了。感兴趣的可以到原贴看看。不过优化后速度可是快了一个数量级啊。

我之前在代码只是抛砖引玉,这里又让我想到了一点,既然之前要减少内存消耗,是不是该引入迭代器了。



--------------------------------------- 以下为原贴---------------------------------------
[C++] 纯文本查看 复制代码
#[no_mangle]
pub extern "stdcall" fn rustforin() {
    let mut sum = String::new();

    for i in 1..=99 {
        for j in 1..=99 {
            for k in 1..99 {
                if i == j || i == k || j == k {
                } else {

                    sum += &format!("{:02} {:02} {:02}\r\n", i, j, k);
                }
            }
        }
    }
    let mut file = std::fs::File::create("三位数.txt").expect("创建失败");
    file.write_all(sum.as_bytes()).expect("创建失败");
}





由于易语言对10万以上的文本处理循环非常不友好,比如下面这个帖子
https://bbs.125.la/forum.php?mod=viewthread&tid=14787065

我写的两种方式都要10多秒到20秒左右才能处理完。
首先新建rust库项目,在命令行输入



cargo new  testdll --lib

在项目目录中找到Cargo.toml文件,打开该文件,直接在最后添加

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

进到src文件夹,打开lis.rs,删掉原有的例子,写你自己的dll

[C++] 纯文本查看 复制代码
use std::io::Write;
#[no_mangle]
pub extern "stdcall" fn rustforin() {
    let mut sum = String::new();
    let mut a;
    let mut b;
    let mut c;
    for i in 1..=99 {
        for j in 1..=99 {
            for k in 1..99 {
                if i == j || i == k || j == k {
                } else {
                    if i < 10 {
                        a = String::from("0") + &i.to_string();
                    } else {
                        a = i.to_string();
                    }
                    if j < 10 {
                        b = String::from("0") + &j.to_string();
                    } else {
                        b = j.to_string();
                    }
                    if k < 10 {
                        c = String::from("0") + &k.to_string();
                    } else {
                        c = k.to_string();
                    }
                    sum = sum + &a + &String::from(" ") + &b + &String::from(" ") + &c + "\r\n";
                }
            }
        }
    }
    let mut file = std::fs::File::create("三位数.txt").expect("创建失败");
    file.write_all(sum.as_bytes()).expect("创建失败");
}


这里要注意函数调用方式
pub extern "stdcall"

最后,编译dll,在命令行输入


cargo build --release --target i686-pc-windows-msvc

红字一定一定要注意,rust默认的是64位编译器,如果直接运行cargo build --release,易语言调用的时候会报错,提示找不到接口。
以下是我的rust配置32位编译器方法,在.cargo文件夹下,找到config.ini,按如下修改,其中linker要选择你自己32位编译器地址。
[target.i686-pc-windows-msvc]
rustflags = ["-C", "target-feature=+crt-static"]
linker = "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\bin\Hostx86\x86\link.exe"

ok,到这dll就完事了,现在把dll添加到易语言里调用一下看看
  
DLL命令名返回值类型公开备 注
rustforin 
DLL库文件名:
TestDLL.dll
在DLL库中对应命令名:
rustforin
参数名类 型传址数组备 注


  
子程序名返回值类型公开备 注
_按钮2_被单击  
变量名类 型静态数组备 注
时间整数型 
三位数排列1 ()
三位数排列 ()
调试输出 (“dll,开始”)
时间 = 取启动时间 ()
rustforin ()
调试输出 (取启动时间 () - 时间)
调试输出 (“dll,完成”)


i支持库列表   支持库注释   
spec特殊功能支持库



20230701222710.png


评分

参与人数 2好评 +1 精币 +2 收起 理由
yanggeyyds + 1 新技能已get√
Lishi8 + 1 + 1 开源精神必须支持~

查看全部评分


发表于 2023-12-1 22:48:30 | 显示全部楼层   浙江省宁波市
6666666666666666666666666
回复 支持 反对

使用道具 举报

结帖率:100% (9/9)
发表于 2023-8-21 22:51:45 | 显示全部楼层   江西省南昌市

建立一个交流群 , 一起交流
回复 支持 反对

使用道具 举报

结帖率:0% (0/1)
 楼主| 发表于 2023-8-21 21:47:08 | 显示全部楼层   河北省邯郸市
菜鸟菜鸡秋水 发表于 2023-8-21 17:07
厉害 , 我都没试过 ,我只是看到了, 这rust  很复杂 ,挺难学 ,
有没有和易语言交互的  dll 案例啊  ? ...

正在写读写内存
回复 支持 反对

使用道具 举报

结帖率:100% (9/9)
发表于 2023-8-21 17:07:36 | 显示全部楼层   江西省南昌市
美稀宗 发表于 2023-8-19 23:53
这个库在rust上可以显示汉字a码,u码rust可以直接使用
比如,进程名取pid
[mw_shl_code=cpp,true]fn getp ...

厉害 , 我都没试过 ,我只是看到了, 这rust  很复杂 ,挺难学 ,
有没有和易语言交互的  dll 案例啊  ?
回复 支持 反对

使用道具 举报

结帖率:0% (0/1)
 楼主| 发表于 2023-8-19 23:53:04 | 显示全部楼层   河北省邯郸市
菜鸟菜鸡秋水 发表于 2023-8-19 19:58
想用rust 和易语言交互的兄弟们 ,  这是一个编码库 ,省的大家找 , 本人没有测试 , 是大公司搞的 https://gi ...

这个库在rust上可以显示汉字a码,u码rust可以直接使用
比如,进程名取pid
[C++] 纯文本查看 复制代码
fn getpid_from_name(pname: &str, wordscase: bool, call_back_arry: &mut Vec<u32>) -> i32 {
    let handle: HANDLE;
    let mut pe32 = &mut PROCESSENTRY32W {
        dwSize: 0,
        cntUsage: 0,
        th32ProcessID: 0,
        th32DefaultHeapID: 0,
        th32ModuleID: 0,
        cntThreads: 0,
        th32ParentProcessID: 0,
        pcPriClassBase: 0,
        dwFlags: 0,
        szExeFile: [0; 260],
    };
    unsafe {
        handle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0).unwrap();
    }

    pe32.dwSize = size_of::<PROCESSENTRY32W>() as u32;

    unsafe {
        if Process32FirstW(handle, pe32) == false {
            CloseHandle(handle);
            println!("获取进程快照句柄失败");
            return -1;
        }
        while Process32NextW(handle, pe32) != false {
            //println!("进程名为{:?}",pe32.szExeFile);
            let text_wide = String::from_utf16(&pe32.szExeFile).unwrap();
            let process_name = text_wide.trim_end_matches("\0");
            //println!("进程名为{:?}",process_name);
            if wordscase != true {
                let cpname = pname.to_lowercase();
                if cpname == process_name.to_lowercase() {
                    call_back_arry.push(pe32.th32ProcessID as u32);
                }
            } else {
                let cpname = pname.to_string();
                if cpname == process_name.to_string() {
                    call_back_arry.push(pe32.th32ProcessID as u32);
                }
            }
        }
        if CloseHandle(handle) == true {
            println!("关闭成功");
        }
        if call_back_arry.get(0) == None {
            return 0;
        } else {
            return call_back_arry[0] as i32;
        }
    }
}


这里PROCESSENTRY32W直接返回的就是u码,rust可以直接显示,如果易语言要调用这个接口,需转码才能显示。
这个库的好处是,如果涉及到32位读内存文本型(),可以直接返回汉字a码,否则只能通过返回字节数组的形式,即读内存字节集(),再通过到文本()转化为汉字
回复 支持 反对

使用道具 举报

结帖率:100% (9/9)
发表于 2023-8-19 19:58:22 | 显示全部楼层   江西省南昌市
想用rust 和易语言交互的兄弟们 ,  这是一个编码库 ,省的大家找 , 本人没有测试 , 是大公司搞的 https://github.com/hsivonen/encoding_rs
回复 支持 反对

使用道具 举报

结帖率:100% (9/9)
发表于 2023-8-17 21:40:33 | 显示全部楼层   江西省南昌市
我电脑找到了对应的link.exe ,
但是提示错误,
   Compiling testdll v0.1.0 (E:\b各种语言代码\rustCode\testdll)
error[E0463]: can't find crate for `std`
  |
  = note: the `i686-pc-windows-msvc` target may not be installed
  = help: consider downloading the target with `rustup target add i686-pc-windows-msvc`

error: requires `sized` lang_item

For more information about this error, try `rustc --explain E0463`.

最后用rust 的方法 安装了对应依赖 ,好像编译过了,开心

按照提示  用  rustup target add i686-pc-windows-msvc 安装对应依赖,就好了,
编译结果在  \target\i686-pc-windows-msvc\release  这个目录,有对应dll ,
00.png
回复 支持 反对

使用道具 举报

发表于 2023-8-14 17:32:43 | 显示全部楼层   浙江省杭州市
回复 支持 反对

使用道具 举报

发表于 2023-8-14 17:32:28 | 显示全部楼层   浙江省杭州市
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 致发广告者

发布主题 收藏帖子 返回列表

sitemap| 易语言源码| 易语言教程| 易语言论坛| 诚聘英才| 易语言模块| 手机版| 广告投放| 精易论坛
拒绝任何人以任何形式在本论坛发表与中华人民共和国法律相抵触的言论,本站内容均为会员发表,并不代表精易立场!
论坛帖子内容仅用于技术交流学习和研究的目的,严禁用于非法目的,否则造成一切后果自负!如帖子内容侵害到你的权益,请联系我们!
防范网络诈骗,远离网络犯罪 违法和不良信息举报电话0663-3422125,QQ: 800073686,邮箱:800073686@b.qq.com
Powered by Discuz! X3.4 揭阳市揭东区精易科技有限公司 ( 粤ICP备12094385号-1) 粤公网安备 44522102000125 增值电信业务经营许可证 粤B2-20192173

快速回复 返回顶部 返回列表