From e1fcc90c13b037da1501aa53b3491d27081598ca Mon Sep 17 00:00:00 2001 From: Antony Lee Date: Tue, 17 May 2022 10:41:20 +0200 Subject: [PATCH] Slightly simplify tcl/tk load in extension. Always load all three C functions both on Windows and on non-Windows, for simplicity (the extra dlsym call should have negligible cost). --- src/_tkagg.cpp | 46 +++++++++++++++++----------------------------- src/_tkmini.h | 3 +-- 2 files changed, 18 insertions(+), 31 deletions(-) diff --git a/src/_tkagg.cpp b/src/_tkagg.cpp index a2c99b50486b..eae5c5a0e88b 100644 --- a/src/_tkagg.cpp +++ b/src/_tkagg.cpp @@ -51,11 +51,9 @@ static int convert_voidptr(PyObject *obj, void *p) // extension module or loaded Tk libraries at run-time. static Tk_FindPhoto_t TK_FIND_PHOTO; static Tk_PhotoPutBlock_t TK_PHOTO_PUT_BLOCK; -#ifdef WIN32_DLL // Global vars for Tcl functions. We load these symbols from the tkinter // extension module or loaded Tcl libraries at run-time. static Tcl_SetVar_t TCL_SETVAR; -#endif static PyObject *mpl_tk_blit(PyObject *self, PyObject *args) { @@ -225,28 +223,24 @@ static PyMethodDef functions[] = { // Functions to fill global Tcl/Tk function pointers by dynamic loading. template -int load_tk(T lib) +bool load_tcl_tk(T lib) { - // Try to fill Tk global vars with function pointers. Return the number of - // functions found. - return - !!(TK_FIND_PHOTO = - (Tk_FindPhoto_t)dlsym(lib, "Tk_FindPhoto")) + - !!(TK_PHOTO_PUT_BLOCK = - (Tk_PhotoPutBlock_t)dlsym(lib, "Tk_PhotoPutBlock")); + // Try to fill Tcl/Tk global vars with function pointers. Return whether + // all of them have been filled. + if (void* ptr = dlsym(lib, "Tcl_SetVar")) { + TCL_SETVAR = (Tcl_SetVar_t)ptr; + } + if (void* ptr = dlsym(lib, "Tk_FindPhoto")) { + TK_FIND_PHOTO = (Tk_FindPhoto_t)ptr; + } + if (void* ptr = dlsym(lib, "Tk_PhotoPutBlock")) { + TK_PHOTO_PUT_BLOCK = (Tk_PhotoPutBlock_t)ptr; + } + return TCL_SETVAR && TK_FIND_PHOTO && TK_PHOTO_PUT_BLOCK; } #ifdef WIN32_DLL -template -int load_tcl(T lib) -{ - // Try to fill Tcl global vars with function pointers. Return the number of - // functions found. - return - !!(TCL_SETVAR = (Tcl_SetVar_t)dlsym(lib, "Tcl_SetVar")); -} - /* On Windows, we can't load the tkinter module to get the Tcl/Tk symbols, * because Windows does not load symbols into the library name-space of * importing modules. So, knowing that tkinter has already been imported by @@ -259,7 +253,6 @@ void load_tkinter_funcs(void) HANDLE process = GetCurrentProcess(); // Pseudo-handle, doesn't need closing. HMODULE* modules = NULL; DWORD size; - bool tcl_ok = false, tk_ok = false; if (!EnumProcessModules(process, NULL, 0, &size)) { PyErr_SetFromWindowsErr(0); goto exit; @@ -273,11 +266,8 @@ void load_tkinter_funcs(void) goto exit; } for (unsigned i = 0; i < size / sizeof(HMODULE); ++i) { - if (!tcl_ok) { - tcl_ok = load_tcl(modules[i]); - } - if (!tk_ok) { - tk_ok = load_tk(modules[i]); + if (load_tcl_tk(modules[i])) { + return; } } exit: @@ -301,7 +291,7 @@ void load_tkinter_funcs(void) // Try loading from the main program namespace first. main_program = dlopen(NULL, RTLD_LAZY); - if (load_tk(main_program)) { + if (load_tcl_tk(main_program)) { goto exit; } // Clear exception triggered when we didn't find symbols above. @@ -324,7 +314,7 @@ void load_tkinter_funcs(void) PyErr_SetString(PyExc_RuntimeError, dlerror()); goto exit; } - if (load_tk(tkinter_lib)) { + if (load_tcl_tk(tkinter_lib)) { goto exit; } @@ -353,11 +343,9 @@ PyMODINIT_FUNC PyInit__tkagg(void) load_tkinter_funcs(); if (PyErr_Occurred()) { return NULL; -#ifdef WIN32_DLL } else if (!TCL_SETVAR) { PyErr_SetString(PyExc_RuntimeError, "Failed to load Tcl_SetVar"); return NULL; -#endif } else if (!TK_FIND_PHOTO) { PyErr_SetString(PyExc_RuntimeError, "Failed to load Tk_FindPhoto"); return NULL; diff --git a/src/_tkmini.h b/src/_tkmini.h index b3297ff15660..85f245815e4c 100644 --- a/src/_tkmini.h +++ b/src/_tkmini.h @@ -100,11 +100,10 @@ typedef int (*Tk_PhotoPutBlock_t) (Tcl_Interp *interp, Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height, int compRule); -#ifdef WIN32_DLL /* Typedefs derived from function signatures in Tcl header */ +/* Tcl_SetVar typedef */ typedef const char *(*Tcl_SetVar_t)(Tcl_Interp *interp, const char *varName, const char *newValue, int flags); -#endif #ifdef __cplusplus } pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy