diff options
Diffstat (limited to 'v_windows/v/examples/dynamic_library_loading')
3 files changed, 92 insertions, 0 deletions
diff --git a/v_windows/v/examples/dynamic_library_loading/modules/library/library.v b/v_windows/v/examples/dynamic_library_loading/modules/library/library.v new file mode 100644 index 0000000..ed3658c --- /dev/null +++ b/v_windows/v/examples/dynamic_library_loading/modules/library/library.v @@ -0,0 +1,19 @@ +module library + +// add_1 is exported with the C name `add_1`. +// It can be called by external programs, when the module is compiled +// as a shared library. +// It is exported, because the function is declared as public with `pub`. +// The exported C name is `add_1`, because of the export: tag. +// (Normally, the exported name is a V mangled version based on the module +// name followed by __, followed by the fn name, i.e. it would have been +// `library__add_1`, if not for the export: tag). +[export: 'add_1'] +pub fn add_1(x int, y int) int { + return my_private_function(x + y) +} + +// this function is not exported and will not be visible to external programs. +fn my_private_function(x int) int { + return 1 + x +} diff --git a/v_windows/v/examples/dynamic_library_loading/use.v b/v_windows/v/examples/dynamic_library_loading/use.v new file mode 100644 index 0000000..71a0099 --- /dev/null +++ b/v_windows/v/examples/dynamic_library_loading/use.v @@ -0,0 +1,17 @@ +module main + +import os +import dl + +type FNAdder = fn (int, int) int + +fn main() { + library_file_path := os.join_path(os.getwd(), dl.get_libname('library')) + handle := dl.open_opt(library_file_path, dl.rtld_lazy) ? + eprintln('handle: ${ptr_str(handle)}') + mut f := FNAdder(0) + f = dl.sym_opt(handle, 'add_1') ? + eprintln('f: ${ptr_str(f)}') + res := f(1, 2) + eprintln('res: $res') +} diff --git a/v_windows/v/examples/dynamic_library_loading/use_test.v b/v_windows/v/examples/dynamic_library_loading/use_test.v new file mode 100644 index 0000000..a224b2a --- /dev/null +++ b/v_windows/v/examples/dynamic_library_loading/use_test.v @@ -0,0 +1,56 @@ +module main + +import os +import dl + +const ( + vexe = os.real_path(os.getenv('VEXE')) + cfolder = os.dir(@FILE) + so_ext = dl.dl_ext + library_file_name = os.join_path(cfolder, dl.get_libname('library')) +) + +fn test_vexe() { + // dump(vexe) + assert vexe != '' + // dump(os.executable()) + // dump(@FILE) + // dump(cfolder) + // dump(so_ext) + // dump(library_file_name) +} + +fn test_can_compile_library() { + os.chdir(cfolder) or {} + os.rm(library_file_name) or {} + v_compile('-d no_backtrace -o library -shared modules/library/library.v') + assert os.is_file(library_file_name) +} + +fn test_can_compile_main_program() { + os.chdir(cfolder) or {} + assert os.is_file(library_file_name) + result := v_compile('run use.v') + // dump(result) + assert result.output.contains('res: 4') + os.rm(library_file_name) or {} +} + +fn test_can_compile_and_use_library_with_skip_unused() { + os.chdir(cfolder) or {} + os.rm(library_file_name) or {} + v_compile('-skip-unused -d no_backtrace -o library -shared modules/library/library.v') + assert os.is_file(library_file_name) + result := v_compile('run use.v') + assert result.output.contains('res: 4') + os.rm(library_file_name) or {} +} + +fn v_compile(vopts string) os.Result { + cmd := '"$vexe" -showcc $vopts' + // dump(cmd) + res := os.execute_or_exit(cmd) + // dump(res) + assert res.exit_code == 0 + return res +} |