bass-rs使用

这是学习Rust写的第一篇文章,记录下我是用bass-rs这个库遇到的一些问题,最近在学习rust_vcl,想按照他govclmp3Player例子用rust_vcl来实现一遍,就在crates.io中搜到了bass-rs

下载之后用bass自带的lib编译不过,就用dumpbin输出导入表自己生成了个lib,写了个测试调用了下BASS_GetVersion没啥问题,就直接用了,下面是编译时报的连接错误:

'error LNK2019: 无法解析的外部符号 _BASS_Init,函数 __ZN6testrs4main17h116efb1a54a26a52E 中引用了该符号\r\nE:\Downloads \testrs\target\debug\deps\testrs.exe : fatal error LNK1120: 1 个无法解析的外部命令\r\n'

结果在调用BASS_Init的时候出问题了,只要调用这个函数在程序结束时就会报错:

   Finished dev [unoptimized + debuginfo] target(s) in 0.01s
    Running `target\debug\testrs.exe`
rror: process didn't exit successfully: `target\debug\testrs.exe` (exit code: 0xc0000005, STATUS_ACCESS_VIOLATION)

试了很多方法都不行,只能上x64dbg看看了:

003F1077 | 31C0                     | xor eax,eax                                                                                      |
003F1079 | C70424 FFFFFFFF          | mov dword ptr ss:[esp],FFFFFFFF                                                                  |
003F1080 | C74424 04 44AC0000       | mov dword ptr ss:[esp+4],AC44                                                                    | [esp+4]:"LdrpInitializeProcess"
003F1088 | C74424 08 00000000       | mov dword ptr ss:[esp+8],0                                                                       | [esp+8]:"minkernel\\ntdll\\ldrinit.c"
003F1090 | C74424 0C 00000000       | mov dword ptr ss:[esp+C],0                                                                       |
003F1098 | C74424 10 00000000       | mov dword ptr ss:[esp+10],0                                                                      |
003F10A0 | 894424 14                | mov dword ptr ss:[esp+14],eax                                                                    |
003F10A4 | E8 57610100              | call <testrs._BASS_Init>                                                                         |
003F10A9 | 83C4 18                  | add esp,18                                                                                       | main.rs:8
003F10AC | C3                       | ret                                                                                              |

这里可以看到生成的汇编在调用函数之后会外平栈,但是看bass.h头文件知道bass.dll的函数都是用WINAPI导出的,也就是说BASS_Init是内平栈:

上面的图片已经说明了调用BASS_Init之后堆栈已经平衡了,但是add esp,18又平了一次导致的错误。

问题原因找到了,接下来是解决方法了,根据官方手册的内容,bass.dll的方法在Win32下应该用extern "stdcall", 但是源码里是extern "C",这里为了跨平台应该使用extern "system",并且bass.lib也不需要生成,直接链接官网下载的包中的bass.lib就正常了。

转载请注明: 本文《bass-rs使用》来源于bstaint的博客

没有评论: