diff --git a/lektord/c/dll.cc b/lektord/c/dll.cc index f4928a128731dcbc952c4ab6cc83d935abf02462..b8e06ddecffa83d0e0ddecb181a5fd7a292db8c6 100644 --- a/lektord/c/dll.cc +++ b/lektord/c/dll.cc @@ -1,47 +1,17 @@ #include <windows.h> -void *__imp____lkt_abort; -void *__imp____lkt_log_rs; -void *__imp_lkt_toggle_play_state; -void *__imp_lkt_play_next; -void *__imp_lkt_play_prev; - -#define IMPORT_FUNCTION(name) \ - *(void **)&__imp_##name = (void *)GetProcAddress(GetModuleHandle(0), "__imp_" #name) - BOOL WINAPI -DllMain(HINSTANCE hinstDLL, // handle to DLL module - DWORD fdwReason, // reason for calling function - LPVOID lpvReserved) // reserved +DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { - // Perform actions based on the reason for calling. switch (fdwReason) { - case DLL_PROCESS_ATTACH: - IMPORT_FUNCTION(___lkt_abort); - IMPORT_FUNCTION(___lkt_log_rs); - IMPORT_FUNCTION(lkt_toggle_play_state); - IMPORT_FUNCTION(lkt_play_next); - IMPORT_FUNCTION(lkt_play_prev); - - // Initialize once for each new process. - // Return FALSE to fail DLL load. - break; - - case DLL_THREAD_ATTACH: - // Do thread-specific initialization. - break; - - case DLL_THREAD_DETACH: - // Do thread-specific cleanup. - break; - + case DLL_PROCESS_ATTACH: break; + case DLL_THREAD_ATTACH: break; + case DLL_THREAD_DETACH: break; case DLL_PROCESS_DETACH: if (lpvReserved != nullptr) { - break; // do not do cleanup if process termination scenario + break; } - - // Perform any necessary cleanup. break; } - return TRUE; // Successful DLL_PROCESS_ATTACH. + return TRUE; } diff --git a/lektord/c/module_qt_window.cc b/lektord/c/module_qt_window.cc index d9d03f2dd240644e98ac6d9def1e125ece78e904..ef4dab0b1c32621dcbb55d3bbd1663a17418b1de 100644 --- a/lektord/c/module_qt_window.cc +++ b/lektord/c/module_qt_window.cc @@ -20,10 +20,43 @@ ___create_mpv_widget(void *arg) return std::bit_cast<void *>((static_cast<size_t>(app.exec()))); } +#if defined(LKT_OS_MINGW) && (LKT_OS_MINGW == 1) +void *__imp____lkt_abort; +void *__imp____lkt_log_rs; +void *__imp_lkt_toggle_play_state; +void *__imp_lkt_play_next; +void *__imp_lkt_play_prev; +#endif + extern "C" { DLL_EXPORT int -mod_new(void) +mod_new(void UNUSED *func_ptrs) { +#if defined(LKT_OS_MINGW) && (LKT_OS_MINGW == 1) + struct lkt_func_ptrs { + void *___lkt_log_rs; + void *___lkt_abort; + void *lkt_play_next; + void *lkt_play_prev; + void *lkt_toggle_play_state; + }; +#define IMPORT_FUNCTION(name) \ + { \ + struct lkt_func_ptrs *ptrs = (struct lkt_func_ptrs *)func_ptrs; \ + __imp_##name = ptrs->name; \ + LOG_INFO("DLL", #name " := %p\n", __imp_##name); \ + } + fprintf( + stderr, + "loading the lektor_c.dll, init the pointers to reuse functionalities from executable\n"); + IMPORT_FUNCTION(___lkt_log_rs); + IMPORT_FUNCTION(___lkt_abort); + IMPORT_FUNCTION(lkt_toggle_play_state); + IMPORT_FUNCTION(lkt_play_next); + IMPORT_FUNCTION(lkt_play_prev); +#undef IMPORT_FUNCTION +#endif + LOG_DEBUG("WINDOW", "initializing a new window"); if (module == nullptr) { module = LKT_ALLOC_STRUCT(module_qt_window_s); diff --git a/lektord/c/module_qt_window.hh b/lektord/c/module_qt_window.hh index bede7baadc680960c382fd6fe3be894fa0526b22..acea77e28a5baf929d2e0b03b679596492c197d4 100644 --- a/lektord/c/module_qt_window.hh +++ b/lektord/c/module_qt_window.hh @@ -13,7 +13,7 @@ struct module_qt_window_s { }; extern "C" { -DLL_EXPORT int mod_new(void); +DLL_EXPORT int mod_new(void *func_ptrs); DLL_EXPORT int mod_close(void); DLL_EXPORT int mod_toggle_pause(void); DLL_EXPORT int mod_stop_playback(void); diff --git a/lektord/src/c_wrapper/loging.rs b/lektord/src/c_wrapper/loging.rs index 0f925532bcfaf463fd2292752aded75dd833eec1..b39e412b2e7eba28cc8d05f1ab8c0afc348717ca 100644 --- a/lektord/src/c_wrapper/loging.rs +++ b/lektord/src/c_wrapper/loging.rs @@ -8,7 +8,8 @@ use std::{ /// This function is intended to be called by `___lkt_log` with valid CStrings, i.e., the strings /// must be null-terminated. Note that from the C-side of things, you can't pass null pointers. #[export_name = "___lkt_log_rs"] -unsafe extern "C" fn lkt_log_rs( +#[inline(never)] +pub unsafe extern "C" fn lkt_log_rs( log_level: c_int, section: NonNull<c_char>, function: NonNull<c_char>, diff --git a/lektord/src/c_wrapper/mod.rs b/lektord/src/c_wrapper/mod.rs index 52a064f2b59f0cc2fbcf5a562af5923bfc1d9960..e5be5087b8ab9f6bf6f36dd0d8051053b0ad6da4 100644 --- a/lektord/src/c_wrapper/mod.rs +++ b/lektord/src/c_wrapper/mod.rs @@ -41,8 +41,24 @@ enum PlayerEvent { /// Init the player module! pub(crate) fn init_player_module(ptr: LektorStatePtr, config: LektorPlayerConfig) -> Result<()> { + #[repr(C)] + struct FunctionTable { + log: unsafe extern "C" fn( + c_int, + NonNull<c_char>, + NonNull<c_char>, + NonNull<c_char>, + u64, + NonNull<c_char>, + ), + abort: extern "C" fn(), + next: extern "C" fn(), + prev: extern "C" fn(), + toggle: extern "C" fn(c_int), + } + extern "C" { - fn mod_new() -> c_int; + fn mod_new(_: *const FunctionTable) -> c_int; fn mod_set_msg_options(_: NonNull<c_char>, _: u64, _: u64) -> c_int; fn mod_set_force_x11(_: bool) -> c_int; } @@ -106,7 +122,14 @@ pub(crate) fn init_player_module(ptr: LektorStatePtr, config: LektorPlayerConfig } // Create the player - if 0 != mod_new() { + let table = FunctionTable { + log: loging::lkt_log_rs, + next: lkt_play_next, + prev: lkt_play_prev, + toggle: lkt_toggle_play_state, + abort: lkt_abort, + }; + if 0 != mod_new(&table as *const _) { anyhow::bail!("failed to init the player module") } Ok(())