├── testapp ├── .gitignore ├── build.hxml └── src │ ├── Dl.hx │ ├── Main.hx │ └── MyLibrary.hx ├── my_library ├── .gitignore ├── Cargo.toml └── src │ └── lib.rs ├── README.md └── .gitignore /testapp/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /my_library/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | **/*.rs.bk 3 | Cargo.lock 4 | -------------------------------------------------------------------------------- /testapp/build.hxml: -------------------------------------------------------------------------------- 1 | -cp src 2 | -main Main 3 | -dce full 4 | 5 | -cpp build -------------------------------------------------------------------------------- /my_library/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "my_libary" 3 | version = "0.1.0" 4 | authors = ["Kenton Hamaluik "] 5 | edition = "2018" 6 | 7 | [lib] 8 | name = "my_libary" 9 | crate-type = ["cdylib"] 10 | 11 | [dependencies] 12 | -------------------------------------------------------------------------------- /testapp/src/Dl.hx: -------------------------------------------------------------------------------- 1 | 2 | package; 3 | 4 | /** 5 | dynamic linking 6 | */ 7 | @:include("dlfcn.h") 8 | extern class Dl { 9 | @:native("RTLD_NOW") 10 | public static var RTLD_NOW: Int; 11 | 12 | @:native("dlopen") 13 | public static function open(filename: cpp.ConstCharStar, flags: Int): cpp.RawPointer; 14 | 15 | @:native("dlerror") 16 | public static function error(): cpp.RawPointer; 17 | 18 | @:native("dlsym") 19 | public static function sym(lib: cpp.RawPointer, sym: cpp.ConstCharStar): cpp.RawPointer; 20 | 21 | @:native("dlclose") 22 | public static function close(lib:cpp.RawPointer): Int; 23 | } -------------------------------------------------------------------------------- /testapp/src/Main.hx: -------------------------------------------------------------------------------- 1 | package; 2 | 3 | // https://gist.github.com/ibilon/02e3e4e7f2c825444501a2e878e0ec7f 4 | 5 | class Main { 6 | public static function main () { 7 | if(Sys.args().length != 1) { 8 | trace("Usage: testapp "); 9 | Sys.exit(0); 10 | } 11 | 12 | if(!MyLibrary.load(Sys.args()[0])) { 13 | Sys.exit(1); 14 | } 15 | 16 | trace("Adding two..."); 17 | for(i in 0...10) { 18 | trace(i + " -> " + MyLibrary.add_two(i)); 19 | } 20 | 21 | trace("Calculating the sum of the first 10 numbers in the Fibonacci sequence:"); 22 | trace(MyLibrary.fib_sum(10)); 23 | 24 | MyLibrary.unload(); 25 | } 26 | } -------------------------------------------------------------------------------- /my_library/src/lib.rs: -------------------------------------------------------------------------------- 1 | #[no_mangle] 2 | pub extern "C" fn add_two(x: u64) -> u64 { 3 | x + 2 4 | } 5 | 6 | // from https://riptutorial.com/rust/example/21013/custom-iterator 7 | 8 | struct Fibonacci(u64, u64); 9 | 10 | impl Iterator for Fibonacci { 11 | type Item = u64; 12 | 13 | fn next(&mut self) -> Option { 14 | let ret = self.0; 15 | self.0 = self.1; 16 | self.1 += ret; 17 | Some(ret) 18 | } 19 | } 20 | 21 | #[no_mangle] 22 | pub extern "C" fn fib_sum(times: usize) -> u64 { 23 | Fibonacci(0, 1).take(times).sum() 24 | } 25 | 26 | #[cfg(test)] 27 | mod tests { 28 | #[test] 29 | fn fib_sum_works() { 30 | use super::fib_sum; 31 | assert_eq!(fib_sum(10), 88); 32 | } 33 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # haxe_load_dll 2 | 3 | Sample showing creating a dynamic library (with [Rust](https://www.rust-lang.org/)) and loading and using it in [Haxe](https://haxe.org/) (for the CPP target). 4 | 5 | ## Instructions 6 | 7 | 1. Compile the dynamic library `my_library` (using rust): 8 | ```bash 9 | $ cd my_library && cargo build --release && cd .. 10 | ``` 11 | 2. Compile the haxe program `testapp`: 12 | ```bash 13 | $ cd testapp && haxe build.hxml 14 | ``` 15 | 3. Run it!: 16 | ```bash 17 | $ ./build/Main ../my_library/target/release/libmy_libary.so 18 | src/Main.hx:16: Adding two... 19 | src/Main.hx:18: 0 -> 2 20 | src/Main.hx:18: 1 -> 3 21 | src/Main.hx:18: 2 -> 4 22 | src/Main.hx:18: 3 -> 5 23 | src/Main.hx:18: 4 -> 6 24 | src/Main.hx:18: 5 -> 7 25 | src/Main.hx:18: 6 -> 8 26 | src/Main.hx:18: 7 -> 9 27 | src/Main.hx:18: 8 -> 10 28 | src/Main.hx:18: 9 -> 11 29 | src/Main.hx:21: Calculating the sum of the first 10 numbers in the Fibonacci sequence: 30 | src/Main.hx:22: 88 31 | ``` -------------------------------------------------------------------------------- /testapp/src/MyLibrary.hx: -------------------------------------------------------------------------------- 1 | package; 2 | 3 | class MyLibrary { 4 | static var lib: cpp.RawPointer; 5 | static var _add_two: cpp.RawPointer; 6 | static var _fib_sum: cpp.RawPointer; 7 | 8 | public static function load(path: String): Bool { 9 | lib = Dl.open(path, Dl.RTLD_NOW); 10 | if(lib == null) { 11 | trace("can't find library"); 12 | return false; 13 | } 14 | Dl.error(); 15 | 16 | _add_two = Dl.sym(lib, "add_two"); 17 | if(_add_two == null) { 18 | trace("can't find add_two"); 19 | Dl.close(lib); 20 | return false; 21 | } 22 | 23 | _fib_sum = Dl.sym(lib, "fib_sum"); 24 | if(_fib_sum == null) { 25 | trace("can't find fib_sum"); 26 | Dl.close(lib); 27 | return false; 28 | } 29 | 30 | return true; 31 | } 32 | 33 | public static function unload(): Void { 34 | Dl.close(lib); 35 | } 36 | 37 | public static function add_two(x: Int): Int { 38 | var xu: cpp.UInt64 = x; 39 | var y: cpp.UInt64 = untyped __cpp__("reinterpret_cast({0})({1})", _add_two, xu); 40 | return y; 41 | } 42 | 43 | public static function fib_sum(times: Int): Int { 44 | var xu: cpp.SizeT = times; 45 | var y: cpp.UInt64 = untyped __cpp__("reinterpret_cast({0})({1})", _fib_sum, xu); 46 | return y; 47 | } 48 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.gitignore.io/api/windows,osx,linux,visualstudiocode 3 | # Edit at https://www.gitignore.io/?templates=windows,osx,linux,visualstudiocode 4 | 5 | ### Linux ### 6 | *~ 7 | 8 | # temporary files which can be created if a process still has a handle open of a deleted file 9 | .fuse_hidden* 10 | 11 | # KDE directory preferences 12 | .directory 13 | 14 | # Linux trash folder which might appear on any partition or disk 15 | .Trash-* 16 | 17 | # .nfs files are created when an open file is removed but is still being accessed 18 | .nfs* 19 | 20 | ### OSX ### 21 | # General 22 | .DS_Store 23 | .AppleDouble 24 | .LSOverride 25 | 26 | # Icon must end with two \r 27 | Icon 28 | 29 | # Thumbnails 30 | ._* 31 | 32 | # Files that might appear in the root of a volume 33 | .DocumentRevisions-V100 34 | .fseventsd 35 | .Spotlight-V100 36 | .TemporaryItems 37 | .Trashes 38 | .VolumeIcon.icns 39 | .com.apple.timemachine.donotpresent 40 | 41 | # Directories potentially created on remote AFP share 42 | .AppleDB 43 | .AppleDesktop 44 | Network Trash Folder 45 | Temporary Items 46 | .apdisk 47 | 48 | ### VisualStudioCode ### 49 | .vscode/* 50 | !.vscode/settings.json 51 | !.vscode/tasks.json 52 | !.vscode/launch.json 53 | !.vscode/extensions.json 54 | 55 | ### VisualStudioCode Patch ### 56 | # Ignore all local history of files 57 | .history 58 | 59 | ### Windows ### 60 | # Windows thumbnail cache files 61 | Thumbs.db 62 | ehthumbs.db 63 | ehthumbs_vista.db 64 | 65 | # Dump file 66 | *.stackdump 67 | 68 | # Folder config file 69 | [Dd]esktop.ini 70 | 71 | # Recycle Bin used on file shares 72 | $RECYCLE.BIN/ 73 | 74 | # Windows Installer files 75 | *.cab 76 | *.msi 77 | *.msix 78 | *.msm 79 | *.msp 80 | 81 | # Windows shortcuts 82 | *.lnk 83 | 84 | # End of https://www.gitignore.io/api/windows,osx,linux,visualstudiocode 85 | --------------------------------------------------------------------------------