diff --git a/vlib/dl/dl_windows.c.v b/vlib/dl/dl_windows.c.v index 9502f677b5..3356f539c2 100644 --- a/vlib/dl/dl_windows.c.v +++ b/vlib/dl/dl_windows.c.v @@ -20,25 +20,11 @@ type FN_vcleanup_caller = fn () // open loads a given module into the address space of the calling process. pub fn open(filename string, flags int) voidptr { res := C.LoadLibrary(filename.to_wide()) - // Because LoadLibrary has no constructor, this is a workaround - if !isnil(res) { - vinit_caller := FN_vinit_caller(sym(res, '_vinit_caller')) - if !isnil(vinit_caller) { - vinit_caller() - } - } return res } // close frees the loaded a given module. pub fn close(handle voidptr) bool { - // Because FreeLibrary has no destructor, this is a workaround - if !isnil(handle) { - vcleanup_caller := FN_vcleanup_caller(sym(handle, '_vcleanup_caller')) - if !isnil(vcleanup_caller) { - vcleanup_caller() - } - } return C.FreeLibrary(handle) } diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index 11956b93a8..088d886e5d 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -1082,6 +1082,9 @@ pub fn (mut g Gen) finish() { g.handle_embedded_files_finish() if g.pref.is_test { g.gen_c_main_for_tests() + } else if (g.pref.is_shared || g.pref.is_liveshared) && g.pref.os == .windows { + // create DllMain() for windows .dll + g.gen_dll_main() } else { g.gen_c_main() } diff --git a/vlib/v/gen/c/cmain.v b/vlib/v/gen/c/cmain.v index 8667c0944f..b82cf060d9 100644 --- a/vlib/v/gen/c/cmain.v +++ b/vlib/v/gen/c/cmain.v @@ -392,3 +392,33 @@ pub fn (mut g Gen) gen_c_main_trace_calls_hook() { should_trace_c_main := g.pref.should_trace_fn_name('C.main') g.writeln('\tu8 bottom_of_stack = 0; g_stack_base = &bottom_of_stack; v__trace_calls__on_c_main(${should_trace_c_main});') } + +// gen_dll_main create DllMain() for windows .dll +pub fn (mut g Gen) gen_dll_main() { + g.writeln('VV_EXPORTED_SYMBOL BOOL DllMain(HINSTANCE hinst,DWORD fdwReason,LPVOID lpvReserved) { + switch (fdwReason) { + case DLL_PROCESS_ATTACH : { +#if defined(_VGCBOEHM) + GC_set_pages_executable(0); + GC_INIT(); +#endif + _vinit_caller(); + break; + } + case DLL_THREAD_ATTACH : { + break; + } + case DLL_THREAD_DETACH : { + break; + } + case DLL_PROCESS_DETACH : { + _vcleanup_caller(); + break; + } + default: + return false; + } + return true; +} + ') +} diff --git a/vlib/v/gen/c/testdata/closure_shared_lib.c.must_have b/vlib/v/gen/c/testdata/closure_shared_lib.c.must_have index 79f72ec52d..d98668cd15 100644 --- a/vlib/v/gen/c/testdata/closure_shared_lib.c.must_have +++ b/vlib/v/gen/c/testdata/closure_shared_lib.c.must_have @@ -1,2 +1 @@ -__closure_init(); // vinit_caller() -__closure_init(); // main() \ No newline at end of file +__closure_init(); // vinit_caller() \ No newline at end of file diff --git a/vlib/v/tests/create_dll/create_win_dll.c.v b/vlib/v/tests/create_dll/create_win_dll.c.v index 79f6a7bd1a..9cdcb4a08b 100644 --- a/vlib/v/tests/create_dll/create_win_dll.c.v +++ b/vlib/v/tests/create_dll/create_win_dll.c.v @@ -9,23 +9,3 @@ const bar = (foo << 5) + 9 pub fn test_tatltuae() int { return foo + bar } - -@[callconv: stdcall] -@[export: DllMain] -fn main(hinst voidptr, fdw_reason int, lp_reserved voidptr) bool { - match fdw_reason { - C.DLL_PROCESS_ATTACH { - $if static_boehm ? { - C.GC_INIT() - } - C._vinit(0, 0) - } - C.DLL_THREAD_ATTACH {} - C.DLL_THREAD_DETACH {} - C.DLL_PROCESS_DETACH {} - else { - return false - } - } - return true -}