generated from Meekdai/Gmeek-template
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
kylinholmes
committed
Aug 12, 2024
1 parent
a318c31
commit c7e22e7
Showing
7 changed files
with
800 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
# Kylin's :link: https://kylinholmes.github.io | ||
### :page_facing_up: [1](https://kylinholmes.github.io/tag.html) | ||
### :speech_balloon: 0 | ||
### :hibiscus: 19 | ||
### :alarm_clock: 2024-06-22 00:31:55 | ||
### :page_facing_up: [2](https://kylinholmes.github.io/tag.html) | ||
### :speech_balloon: 3 | ||
### :hibiscus: 2357 | ||
### :alarm_clock: 2024-08-12 12:48:23 | ||
### Powered by :heart: [Gmeek](https://github.com/Meekdai/Gmeek) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
## 动态链接crate | ||
|
||
**假设动态库是 impls** | ||
**需要链接到 impls的crate是abi** | ||
|
||
```bash | ||
├── abi # runtime loading library | ||
│ ├── Cargo.toml # specifies dependent libraries to be used for dynamic linking | ||
│ └── src | ||
│ ├── import.rs # import impls to this crate | ||
│ ├── lib.rs # | ||
│ └── main.rs # test main: loading abi and binding interface | ||
├── impls # dynamic link library | ||
│ └── src | ||
│ └── lib.rs # impls | ||
└── README.md | ||
``` | ||
|
||
`main` == loadl ibrary => `abi` == dynamic link ==> `impls` | ||
|
||
设置lib类型为`cdylib` | ||
```toml | ||
# impls/Cargo.toml | ||
[lib] | ||
crate-type = ["cdylib"] | ||
``` | ||
|
||
导出接口 | ||
```rust | ||
// impls/src/lib.rs | ||
#[no_mangle] | ||
pub extern "C" fn add(left: usize, right: usize) -> usize { | ||
left + right | ||
} | ||
``` | ||
|
||
|
||
|
||
设置依赖 | ||
```toml | ||
# abi/Cargo.toml | ||
[dependencies] | ||
impls = { path = "../impls" } | ||
``` | ||
|
||
接口定义 | ||
```rust | ||
#[link(name = "impls")] | ||
extern "C" { | ||
pub fn add(a :usize, b: usize) -> usize; | ||
} | ||
``` | ||
|
||
调用接口 | ||
```rust | ||
println!("Add {}", add(1, 9)); | ||
``` | ||
|
||
## 运行时加载动态库 | ||
因为是运行时加载,所以函数的接口不需要单独定义,通常是绑定到函数指针上 | ||
|
||
```toml | ||
# abi/Cargo.toml | ||
[dependencies] | ||
impls = { path = "../impls" } | ||
libloading = "0.8.5" | ||
``` | ||
|
||
```rust | ||
// abi/src/main.rs | ||
use libloading::{Library, Symbol}; | ||
|
||
static DLL_HANDLE:Lazy<Library> = Lazy::new(|| { | ||
unsafe { | ||
let dll = std::env::args().nth(1).expect("No DLL provided"); | ||
Library::new(dll).expect("Failed to load DLL") | ||
} | ||
}); | ||
|
||
// 定义好函数指针的结构体 | ||
#[derive(Debug)] | ||
struct Interface<'a> { | ||
add: Symbol<'a, extern "C" fn(usize, usize) -> usize>, | ||
init: Symbol<'a, extern "C" fn() -> ()>, | ||
} | ||
|
||
// 加载动态库后,绑定函数指针 | ||
impl <'a> Interface<'a> { | ||
fn new() -> Self { | ||
unsafe { | ||
let add: Symbol<extern "C" fn(usize, usize) -> usize> = DLL_HANDLE.borrow().get(b"add").expect("Failed to load add"); | ||
let init: Symbol<extern "C" fn() -> ()> = DLL_HANDLE.borrow().get(b"init").expect("Failed to load init"); | ||
Interface { | ||
add, | ||
init | ||
} | ||
} | ||
} | ||
} | ||
|
||
fn main() { | ||
let handle = Interface::new(); | ||
(handle.init)(); | ||
let result = (handle.add)(1, 9); | ||
println!("Result: {}", result); | ||
|
||
} | ||
|
||
``` | ||
|
||
|
||
## Demo | ||
项目地址 [Demo](https://github.com/kylinholmes/rs_dynamic_link) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
{"singlePage": [], "startSite": "", "filingNum": "", "onePageListNum": 20, "commentLabelColor": "#006b75", "yearColorList": ["#bc4c00", "#0969da", "#1f883d", "#A333D0"], "i18n": "CN", "themeMode": "manual", "dayTheme": "light_tritanopia", "nightTheme": "dark_tritanopia", "urlMode": "pinyin", "script": "", "style": "", "head": "", "indexScript": "", "indexStyle": "", "bottomText": "", "showPostSource": 1, "iconList": {}, "UTC": 8, "rssSplit": "sentence", "exlink": {}, "needComment": 1, "allHead": "", "title": "Kylin's", "subTitle": "Essay", "avatarUrl": "https://avatars.githubusercontent.com/u/45586871?v=4", "GMEEK_VERSION": "last", "postListJson": {"P1": {"htmlDir": "docs/post/This is a Title.html", "labels": ["documentation"], "postTitle": "This is a Title", "postUrl": "post/This%20is%20a%20Title.html", "postSourceUrl": "https://github.com/kylinholmes/kylinholmes.github.io/issues/1", "commentNum": 3, "wordCount": 19, "description": "# Head 1\r\nsome text\u3002", "top": 0, "createdAt": 1718985782, "style": "", "script": "", "head": "", "ogImage": "https://avatars.githubusercontent.com/u/45586871?v=4", "createdDate": "2024-06-22", "dateLabelColor": "#bc4c00"}}, "singeListJson": {}, "labelColorDict": {"bug": "#d73a4a", "documentation": "#0075ca", "duplicate": "#cfd3d7", "enhancement": "#a2eeef", "good first issue": "#7057ff", "help wanted": "#008672", "invalid": "#e4e669", "question": "#d876e3", "wontfix": "#ffffff"}, "displayTitle": "Kylin's", "faviconUrl": "https://avatars.githubusercontent.com/u/45586871?v=4", "ogImage": "https://avatars.githubusercontent.com/u/45586871?v=4", "primerCSS": "<link href='https://mirrors.sustech.edu.cn/cdnjs/ajax/libs/Primer/21.0.7/primer.css' rel='stylesheet' />", "homeUrl": "https://kylinholmes.github.io", "prevUrl": "disabled", "nextUrl": "disabled"} | ||
{"singlePage": [], "startSite": "", "filingNum": "", "onePageListNum": 20, "commentLabelColor": "#006b75", "yearColorList": ["#bc4c00", "#0969da", "#1f883d", "#A333D0"], "i18n": "CN", "themeMode": "manual", "dayTheme": "light_tritanopia", "nightTheme": "dark_tritanopia", "urlMode": "pinyin", "script": "", "style": "", "head": "", "indexScript": "", "indexStyle": "", "bottomText": "", "showPostSource": 1, "iconList": {}, "UTC": 8, "rssSplit": "sentence", "exlink": {}, "needComment": 1, "allHead": "", "title": "Kylin's", "subTitle": "Essay", "avatarUrl": "https://avatars.githubusercontent.com/u/45586871?v=4", "GMEEK_VERSION": "last", "postListJson": {"P1": {"htmlDir": "docs/post/This is a Title.html", "labels": ["documentation"], "postTitle": "This is a Title", "postUrl": "post/This%20is%20a%20Title.html", "postSourceUrl": "https://github.com/kylinholmes/kylinholmes.github.io/issues/1", "commentNum": 3, "wordCount": 19, "description": "# Head 1\r\nsome text\u3002", "top": 0, "createdAt": 1718985782, "style": "", "script": "", "head": "", "ogImage": "https://avatars.githubusercontent.com/u/45586871?v=4", "createdDate": "2024-06-22", "dateLabelColor": "#bc4c00"}, "P2": {"htmlDir": "docs/post/zai- Rust-zhong- -dong-tai-lian-jie-he-yun-xing-shi-jia-zai-dong-tai-ku.html", "labels": ["rust"], "postTitle": "\u5728 Rust\u4e2d \u52a8\u6001\u94fe\u63a5\u548c\u8fd0\u884c\u65f6\u52a0\u8f7d\u52a8\u6001\u5e93", "postUrl": "post/zai-%20Rust-zhong-%20-dong-tai-lian-jie-he-yun-xing-shi-jia-zai-dong-tai-ku.html", "postSourceUrl": "https://github.com/kylinholmes/kylinholmes.github.io/issues/2", "commentNum": 0, "wordCount": 2338, "description": "## \u52a8\u6001\u94fe\u63a5crate\r\n\r\n**\u5047\u8bbe\u52a8\u6001\u5e93\u662f impls**\r\n**\u9700\u8981\u94fe\u63a5\u5230 impls\u7684crate\u662fabi**\r\n\r\n```bash\r\n\u251c\u2500\u2500 abi # runtime loading library\r\n\u2502 \u251c\u2500\u2500 Cargo.toml # specifies dependent libraries to be used for dynamic linking\r\n\u2502 \u2514\u2500\u2500 src\r\n\u2502 \u251c\u2500\u2500 import.rs # import impls to this crate\r\n\u2502 \u251c\u2500\u2500 lib.rs # \r\n\u2502 \u2514\u2500\u2500 main.rs # test main: loading abi and binding interface\r\n\u251c\u2500\u2500 impls # dynamic link library \r\n\u2502 \u2514\u2500\u2500 src\r\n\u2502 \u2514\u2500\u2500 lib.rs # impls\r\n\u2514\u2500\u2500 README.md\r\n```\r\n\r\n`main` == loadl ibrary => `abi` == dynamic link ==> `impls`\r\n\r\n\u8bbe\u7f6elib\u7c7b\u578b\u4e3a`cdylib`\r\n```toml\r\n# impls/Cargo.toml\r\n[lib]\r\ncrate-type = ['cdylib']\r\n```\r\n\r\n\u5bfc\u51fa\u63a5\u53e3\r\n```rust\r\n// impls/src/lib.rs\r\n#[no_mangle]\r\npub extern 'C' fn add(left: usize, right: usize) -> usize {\r\n left + right\r\n}\r\n```\r\n\r\n\r\n\r\n\u8bbe\u7f6e\u4f9d\u8d56 \r\n```toml\r\n# abi/Cargo.toml\r\n[dependencies]\r\nimpls = { path = '../impls' }\r\n```\r\n\r\n\u63a5\u53e3\u5b9a\u4e49\r\n```rust\r\n#[link(name = 'impls')]\r\nextern 'C' {\r\n pub fn add(a :usize, b: usize) -> usize;\r\n}\r\n```\r\n\r\n\u8c03\u7528\u63a5\u53e3\r\n```rust\r\nprintln!('Add {}', add(1, 9));\r\n```\r\n\r\n## \u8fd0\u884c\u65f6\u52a0\u8f7d\u52a8\u6001\u5e93\r\n\u56e0\u4e3a\u662f\u8fd0\u884c\u65f6\u52a0\u8f7d\uff0c\u6240\u4ee5\u51fd\u6570\u7684\u63a5\u53e3\u4e0d\u9700\u8981\u5355\u72ec\u5b9a\u4e49\uff0c\u901a\u5e38\u662f\u7ed1\u5b9a\u5230\u51fd\u6570\u6307\u9488\u4e0a\r\n\r\n```toml\r\n# abi/Cargo.toml\r\n[dependencies]\r\nimpls = { path = '../impls' }\r\nlibloading = '0.8.5'\r\n```\r\n\r\n```rust\r\n// abi/src/main.rs\r\nuse libloading::{Library, Symbol};\r\n\r\nstatic DLL_HANDLE:Lazy<Library> = Lazy::new(|| {\r\n unsafe {\r\n let dll = std::env::args().nth(1).expect('No DLL provided');\r\n Library::new(dll).expect('Failed to load DLL')\r\n }\r\n});\r\n\r\n// \u5b9a\u4e49\u597d\u51fd\u6570\u6307\u9488\u7684\u7ed3\u6784\u4f53\r\n#[derive(Debug)]\r\nstruct Interface<'a> {\r\n add: Symbol<'a, extern 'C' fn(usize, usize) -> usize>,\r\n init: Symbol<'a, extern 'C' fn() -> ()>,\r\n}\r\n\r\n// \u52a0\u8f7d\u52a8\u6001\u5e93\u540e\uff0c\u7ed1\u5b9a\u51fd\u6570\u6307\u9488\r\nimpl <'a> Interface<'a> {\r\n fn new() -> Self {\r\n unsafe {\r\n let add: Symbol<extern 'C' fn(usize, usize) -> usize> = DLL_HANDLE.borrow().get(b'add').expect('Failed to load add');\r\n let init: Symbol<extern 'C' fn() -> ()> = DLL_HANDLE.borrow().get(b'init').expect('Failed to load init');\r\n Interface {\r\n add,\r\n init\r\n }\r\n }\r\n }\r\n}\r\n\r\nfn main() {\r\n let handle = Interface::new();\r\n (handle.init)();\r\n let result = (handle.add)(1, 9);\r\n println!('Result: {}', result);\r\n \r\n}\r\n\r\n```\r\n\r\n\r\n## Demo\r\n\u9879\u76ee\u5730\u5740 [Demo](https://github.com/kylinholmes/rs_dynamic_link)\u3002", "top": 0, "createdAt": 1723438079, "style": "", "script": "", "head": "", "ogImage": "https://avatars.githubusercontent.com/u/45586871?v=4", "createdDate": "2024-08-12", "dateLabelColor": "#bc4c00"}}, "singeListJson": {}, "labelColorDict": {"bug": "#d73a4a", "documentation": "#0075ca", "duplicate": "#cfd3d7", "enhancement": "#a2eeef", "good first issue": "#7057ff", "help wanted": "#008672", "invalid": "#e4e669", "question": "#d876e3", "rust": "#DA545B", "wontfix": "#ffffff"}, "displayTitle": "Kylin's", "faviconUrl": "https://avatars.githubusercontent.com/u/45586871?v=4", "ogImage": "https://avatars.githubusercontent.com/u/45586871?v=4", "primerCSS": "<link href='https://mirrors.sustech.edu.cn/cdnjs/ajax/libs/Primer/21.0.7/primer.css' rel='stylesheet' />", "homeUrl": "https://kylinholmes.github.io", "prevUrl": "disabled", "nextUrl": "disabled"} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.