主程序是一个可执行文件。 在主程序中声明了全局变量G_B和函数m_add。 然后再动态加载SO文件,在SO中使用。
主程序
static mut G_B: usize = 0;
fn call(){
let lib = libloading::Library::new("./target/debug/libadd.so").unwrap();
let func: libloading::Symbol<fn()> = lib.get(b"add").unwrap();}
func();
}
pub fn m_add(){
unsafe{
G_B += 1;
}
}
libadd.so
extern "Rust" {
static mut G_B: usize;
fn m_add();
}
fn add(){
unsafe{
G_B +=2;
}
}
fn m_call(){
unsafe{
m_add()
}
}
问题
运行主程序后,会报错,报undefined symbol: m_add"
请教下各位大佬,如何解决。谢谢
1
共 6 条评论, 1 页
评论区
写评论是的主程序需要加入编译选项rdynamic. 就可以正常了。
主要是为了给主程序打补丁使用。
--
👇
ssrlive: 這種玩法非常古老了,主程序要特殊設置,可執行文件還有導出函數和變量,插件 DLL 在編譯時導入主程序的函數。這種玩法非常彆扭。 建議你不要這麼做,直接在你的 DLL 的入口函數裏給主程序留一個 回調函數 指針,這樣就非常符合直覺,也非常符合模塊分離原則。
這種玩法非常古老了,主程序要特殊設置,可執行文件還有導出函數和變量,插件 DLL 在編譯時導入主程序的函數。這種玩法非常彆扭。 建議你不要這麼做,直接在你的 DLL 的入口函數裏給主程序留一個 回調函數 指針,這樣就非常符合直覺,也非常符合模塊分離原則。
让 libadd.so 对外开放的函数接受函数和数据指针就好了吧。
如果允许这种情况,那应该要求编译器很强可以像手动检查一样确定依赖关系,但是编译或者链接期应该不会检查到这么智能而是会直接当作循环依赖吧。
https://doc.rust-lang.org/reference/abi.html#the-no_mangle-attribute rust会对函数“改名”,不想要这种行为需要在函数上添加#[no_mangle]属性
如果可以的话,把函数和变量放到库里面去。 不行的话,用Arc::Mutex包装起来,库里面定义一个函数接收他