Rust生成并加载DLL后获取内容到剪切板

Published: 2017-12-29

Tags: Rust

本文总阅读量

这个小Demo演示了如何使用Rust调用DLL内的函数,将获取到的内容复制到系统粘贴板

这个是做什么的呢,前段时间,我用Python写一个小工具,用来读取DLL文件获取设备的标识码,打包成exe后运行起来有点慢,正好在学习Rust,打算用Rust写一个,于是东拼西凑的鼓捣出来,在写的过程中,想到能不能只分发给使用人员一个exe文件,而不用一起发送DLL呢,这样也不用打包分发

搜索了一番,发现似乎不能把DLL文件集成在exe中运行,但是了解到可以换个思路,Rust是可以加载资源到EXE成为静态内容的,如果在编译的过程中,将DLL加载到EXE中,然后运行exe的时候,如果当前目录中有DLL文件,直接调用使用,如果没有DLL文件,运行时生成一个再使用,也是曲线救国的一个思路

extern crate clipboard;
use clipboard::ClipboardProvider;
use clipboard::ClipboardContext;

extern crate libloading;
use libloading::{Library, Symbol};

use std::io::prelude::*;
use std::path::Path;
use std::ffi::CStr;
use std::fs::File;
use std::str;
use std::io;


type GetHylinkDeviceId = unsafe fn() -> *const i8;

const LIBRARY_PATH: &'static str = "PcInfo.dll";
const HYLINK_DLL: &'static [u8] = include_bytes!("PcInfo.dll");


fn generate_hylink_dll(filename: &str, buf: &[u8]) -> io::Result<()> {

    let mut f = try!(File::create(filename));
    try!(f.write(&buf));
    Ok(())

}

fn copy_to_clipboard(x3id: String) {

    let mut ctx: ClipboardContext = ClipboardProvider::new().unwrap();
    println!("{:?}", ctx.get_contents());
    ctx.set_contents(x3id).unwrap();

}

fn get_x3id() -> String {

    // 如果不存在DLL文件,生成DLL
    if !Path::new(LIBRARY_PATH).exists() {
        match generate_hylink_dll(LIBRARY_PATH, HYLINK_DLL) {
            Ok(s) => println!("Generate hylink dll file success {:?}", s),
            Err(r) => println!("Generate hylink dll file failed {:?}", r),
        }
    }

    // 从本地加载DLL文件
    let lib = Library::new(LIBRARY_PATH).unwrap();
    println!("{:?}", lib);

    // 调用DLL获取标识码
    let x3id = unsafe {

        let func: Symbol<GetHylinkDeviceId> = lib.get(b"GetHylinkDeviceId").unwrap();

        let c_buf: *const i8 = func();
        let c_str: &CStr = CStr::from_ptr(c_buf);
        let str_slice: &str = c_str.to_str().unwrap();
        let str_buf: String = str_slice.to_owned();
        str_buf

    };
    x3id
}

fn main() {

    // 从DLL中获取X3标识码
    let x3id: String = get_x3id();
    println!("{:?}", x3id);

    // 将标识码复制到粘贴板
    copy_to_clipboard(x3id)

}

Cargo.toml

[dependencies]
libloading = "0.4"
clipboard = { git = "https://github.com/aweinstock314/rust-clipboard.git" }