1

I write a tool, It can get device id through the dll, and copy the id to clipboard.

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

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

use std::ffi::CStr;
use std::str;

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

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

fn get_x3id() -> String {

    let library_path = "PcInfo.dll";
    println!("Loading add() from {:?}", library_path);

    let lib = Library::new(library_path).unwrap();

    let x3id = unsafe {

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

        let c_buf: *const i8 = func();
        let c_str: &CStr = unsafe { 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() {

    let x3id: String = get_x3id();
    println!("{:?}", x3id);

    copy_to_clipboard(x3id)

}

It works well, I use cargo build it, auto generate an executable. I need to put dll file and exe in the same dir when run it.

I want to know if there is anyway to pack dll file into the exe by cargo?

mcarton
  • 27,633
  • 5
  • 85
  • 95
solideo
  • 129
  • 1
  • 13
  • You can use [`include_bytes!`](https://doc.rust-lang.org/std/macro.include_bytes.html) macro, then create dll file from the data. Duplicate of [this question](https://stackoverflow.com/q/27140634/2731452) – red75prime Sep 04 '17 at 08:45
  • @red75prime Thanks, I search much demo, They use `include_bytes!` load such `hosts` file, convert `&static [u8]` data to `&static str` and output text, I notice that `Library::new()` need `AsRef` parameter, but I don't how to convert `&static [u8]` to `AsRef`. I try to use `str::from_utf8` to convert `&static [u8]` to `&static str`, and `&static str` to `OsStr`, but there is something wrong when `&[u8]` to `&str` (thread 'main' panicked at 'Invalid UTF-8 sequence: invalid utf-8 sequence of 1 bytes from index 2') – solideo Sep 05 '17 at 03:15
  • I thought maybe DLL file can't convert to utf-8, then how should I do to use the dll when load with `include_bytes!` – solideo Sep 05 '17 at 03:20

1 Answers1

1

I known how to do, code example:

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 {

    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),
        }
    }

    // load lib
    let lib = Library::new(LIBRARY_PATH).unwrap();
    println!("{:?}", lib);

    // call
    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() {

    let x3id: String = get_x3id();
    println!("{:?}", x3id);

    copy_to_clipboard(x3id)

}
solideo
  • 129
  • 1
  • 13