| 1 | import dl |
| 2 | import os |
| 3 | import rand |
| 4 | |
| 5 | const vexe = @VEXE |
| 6 | |
| 7 | fn test_interface_from_shared_library_can_call_methods() { |
| 8 | if os.user_os() != 'linux' { |
| 9 | return |
| 10 | } |
| 11 | workdir := os.join_path(os.vtmp_dir(), 'v_plugin_interface_shared_${rand.ulid()}') |
| 12 | os.mkdir_all(workdir) or { panic(err) } |
| 13 | defer { |
| 14 | os.rmdir_all(workdir) or {} |
| 15 | } |
| 16 | lib_src := os.join_path(workdir, 'plugin.v') |
| 17 | host_src := os.join_path(workdir, 'host.v') |
| 18 | lib_bin := os.join_path(workdir, 'plugin') |
| 19 | lib_so := os.join_path(workdir, 'plugin${dl.dl_ext}') |
| 20 | lib_path := lib_so.replace('\\', '\\\\') |
| 21 | library_code := [ |
| 22 | 'module main', |
| 23 | '', |
| 24 | 'pub interface Plugin {', |
| 25 | '\tprint_msg()', |
| 26 | '}', |
| 27 | '', |
| 28 | 'pub struct MyPlugin {}', |
| 29 | '', |
| 30 | 'pub fn (p MyPlugin) print_msg() {', |
| 31 | "\tprintln('Hello, World!')", |
| 32 | '}', |
| 33 | '', |
| 34 | "@[export: 'create_plugin']", |
| 35 | 'pub fn create_plugin() Plugin {', |
| 36 | '\treturn MyPlugin{}', |
| 37 | '}', |
| 38 | ].join('\n') |
| 39 | host_code := [ |
| 40 | 'module main', |
| 41 | '', |
| 42 | 'import dl.loader', |
| 43 | '', |
| 44 | 'pub interface Plugin {', |
| 45 | '\tprint_msg()', |
| 46 | '}', |
| 47 | '', |
| 48 | 'type CreatePlugin = fn () Plugin', |
| 49 | '', |
| 50 | "const lib_path = '${lib_path}'", |
| 51 | '', |
| 52 | 'fn main() {', |
| 53 | '\tmut dl_loader := loader.get_or_create_dynamic_lib_loader(', |
| 54 | '\t\tkey: lib_path', |
| 55 | '\t\tpaths: [lib_path]', |
| 56 | '\t) or { panic(err) }', |
| 57 | '\tdefer {', |
| 58 | '\t\tdl_loader.unregister()', |
| 59 | '\t}', |
| 60 | "\tcreate_plugin_sym := dl_loader.get_sym('create_plugin') or { panic(err) }", |
| 61 | '\tcreate_plugin := CreatePlugin(create_plugin_sym)', |
| 62 | '\tplugin := create_plugin()', |
| 63 | '\tplugin.print_msg()', |
| 64 | '}', |
| 65 | ].join('\n') |
| 66 | os.write_file(lib_src, library_code) or { panic(err) } |
| 67 | os.write_file(host_src, host_code) or { panic(err) } |
| 68 | compile_lib_cmd := '${os.quoted_path(vexe)} -d no_backtrace -shared -o ${os.quoted_path(lib_bin)} ${os.quoted_path(lib_src)}' |
| 69 | run_cmd(compile_lib_cmd) or { panic(err) } |
| 70 | run_host_cmd := '${os.quoted_path(vexe)} -d no_backtrace run ${os.quoted_path(host_src)}' |
| 71 | res := run_cmd(run_host_cmd) or { panic(err) } |
| 72 | assert res.output.contains('Hello, World!') |
| 73 | } |
| 74 | |
| 75 | fn run_cmd(cmd string) !os.Result { |
| 76 | res := os.execute(cmd) |
| 77 | if res.exit_code != 0 { |
| 78 | return error('command failed:\n${cmd}\n${res.output}') |
| 79 | } |
| 80 | return res |
| 81 | } |
| 82 | |