Ilya Zakharevich on Sat, 04 May 2019 14:06:35 +0200 |
[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]
Re: PATCH: support install() on Win: [Re: Please test pari-2.11.2 prerelease 1] |
On Fri, May 03, 2019 at 11:41:39AM +0200, Bill Allombert wrote: > > I attach a patch to es.c. Additionally, a def file should be linked > > to the exe. The patch below shows one way to do it. (I do not know > > how to modify the build environment to make this change to Makefile.) > > This is done in config/Makefile.SH Cannot REALLY test this on Windows! (See my other reports.) > > --- pari-2.11.1/src/language/es.c-pre 2018-07-25 11:00:21.000000000 -0700 > > +++ pari-2.11.1/src/language/es.c 2019-05-02 03:25:45.470881300 -0700 > > @@ -5200,7 +5200,6 @@ install0(const char *name, const char *l > > # define RTLD_GLOBAL 0 > > #endif > > handle = gp_dlopen(lib, RTLD_LAZY|RTLD_GLOBAL); > > - > > if (!handle) > > { > > const char *s = dlerror(); if (s) err_printf("%s\n\n",s); > > @@ -5236,12 +5235,24 @@ gp_LoadLibrary(const char *name) > > } > > return NULL; > > } > > +static int I_m_a_DLL = -1; > > +static HMODULE hmod_exe, hmod_dll; > > static void * > > install0(const char *name, const char *lib) > > { > > HMODULE handle; > > > > - handle = gp_LoadLibrary(lib); > > + if (lib == pari_library_path) { > > + if (I_m_a_DLL < 0) { > > + hmod_exe = hmod_dll = GetModuleHandleA(NULL); > > + if (!hmod_exe /* Can this happen? */ > > + || !(GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS|GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, > > + (LPCSTR)install0, &hmod_dll))) > > + I_m_a_DLL = hmod_exe != hmod_dll; > > + } > > + handle = hmod_dll; > > + } else > > + handle = gp_LoadLibrary(lib); > > if (!handle) > > { > > if (lib) pari_err(e_MISC,"couldn't open dynamic library '%s'",lib); > > What does that do ? Sorry, I thought that this is self-explanatory. To load a function, you need a handle to a loaded ???image??? (DLL or EXE). The ???old??? code hardwires the name of the PARI DLL. This cannot work (neither on Unix, nor on Windows;?????????but I do not know how to fix it on Unix). There are 3 typical cases: a) "addii" is in the EXE file (such as a static build of GP). b) "addii" is in the libPARI.DLL (such as something dynamically linked with libPARI). c) "addii" is in a DLL statically linked with libPARI (such as in Math::Pari DLL?????????which is by default statically linked with [a custom build of] libPARI). The ???old??? implementation supports only the case ???b???. However, in all these cases, "addii" is in the same ???image??? as "install0". So we use GetModuleHandleExA() to find the handle of the ???image??? which contains the function install0(). Then all one needs to support cases ???a??? and ???c??? is the corresponding executables with the export list. The above patch to Makefile links GP-STA.EXE with such a file. This finishes support of the case ???a???. To support ???c???, one needs to link the DLL in question with a suitable .def file (not YOUR worries ;-). > Does > install("addii",GG); > addii(2,3) > work with this patch with gp-sta ? Of course. And with gp-dyn. (This is why I needed to build it.) Hope this helps, Ilya P.S. The code above also distinguishes between ???in an exe??? and ???in a dll??? (at runtime!). ???Just in case???, the answer is stored in the variable I_m_a_DLL (but the particular value is not used?????????we only check whether it is initialized. I *believe* the answer may be useful in some future time?????????but currently do not know where. ;-)