< 返回版块

dingwenjie-nb 发表于 2020-12-29 16:15

rust调用DLL,编译没有问题,执行时报错,感觉是内存问题,但不知道哪里错了,请高手指教,谢谢!

dll中函数原型: long iReadCardBas(int iType, char* pOutInfo)

调用方法:

extern crate libc;
extern crate libloading;

use libc::*;
use libloading::{Library, Symbol};

type IReadCardBas = unsafe fn(i32, *mut u8) -> i32;

pub fn readcardinfo(itype: i32) -> String {
    let lib = Library::new("./SSCardDriver.dll").unwrap();
    unsafe {
        let mut outinfo = [0u8; 1024];
        let poutinfo = outinfo.as_mut_ptr();
        let func: Symbol<IReadCardBas> = lib.get(b"iReadCardBas").unwrap();
        let i = func(itype, poutinfo);
        if i == 0 {
            let sv = &outinfo[0..strlen(outinfo.as_ptr() as *const i8)];
            String::from_utf8_unchecked(sv.to_vec())
        } else {
            i.to_string()
        }
    }
}

错误信息:

    Finished test [unoptimized + debuginfo] target(s) in 0.01s
     Running target\i686-pc-windows-msvc\debug\deps\sbkdriver-34fc5f2476b98ac9.exe

running 1 test
error: test failed, to rerun pass '--lib'

Caused by:
  process didn't exit successfully: `D:\Codes\rust\sbkdriver\target\i686-pc-windows-msvc\debug\deps\sbkdriver-34fc5f2476b98ac9.exe` (exit code: 0xc0000005, STATUS_ACCESS_VIOLATION)

评论区

写评论
zx950921 2020-12-30 18:16

--
👇
dingwenjie-nb: 改成

type IReadCardBas = unsafe extern "stdcall" fn(c_int, *mut c_char) -> c_long;

目前能正常返回了,不过出现了个新的问题

String::from_utf8_lossy(&vec).to_string()

返回字符串中存在中文,都变成�这种乱码了,有啥好方法吗?

--
👇
zx950921: 32位dll要注意导出的函数ABI是什么,最好直接extern 'system'

这要分析你从函数那边拿的字符串的编码是什么,乱码表示你接收的数据的编码跟程序解析的编码不一致,这就没什么快捷的方法解决了,理论上只要解码对了就不会乱码的

作者 dingwenjie-nb 2020-12-30 11:15

感谢,dll是32位的,我使用下面的命令编译。目前程序能正常运行了

--target=i686-pc-windows-msvc

--
👇
Neutron3529:

你load的这个dll是32位的吗?

另外,请用

```//删除这条注释
代码
```//删除这条注释

这种方式把代码括起来

现在的写法真的好难看

作者 dingwenjie-nb 2020-12-30 11:13

改成

type IReadCardBas = unsafe extern "stdcall" fn(c_int, *mut c_char) -> c_long;

目前能正常返回了,不过出现了个新的问题

String::from_utf8_lossy(&vec).to_string()

返回字符串中存在中文,都变成�这种乱码了,有啥好方法吗?

--
👇
zx950921: 32位dll要注意导出的函数ABI是什么,最好直接extern 'system'

zx950921 2020-12-30 10:08

32位dll要注意导出的函数ABI是什么,最好直接extern 'system'

Neutron3529 2020-12-30 09:52

你load的这个dll是32位的吗?

另外,请用

```//删除这条注释
代码
```//删除这条注释

这种方式把代码括起来

现在的写法真的好难看

1 共 5 条评论, 1 页