I'm trying to embed python in my C++ application.
For convenience I would like to place all modules (Lib
folder) in a single zip file.
However, some modules rely on *pyd
and .dll
files that can not be loaded from memory (since windows cannot load dlls from memory).
There is the ZipExtImporter package* that seems to circumvent this issue by loading in memory the natives components via the memory module (credit Joachim Bauch).
(see also : load pyd files from a zip from embedded python )
However, I do not want to load from memory, as on a 32Bit computer the virtual address space of the calling process may be limited.
Then I'm wondering if there is a way to redirect call to those natives components to a folder that contains all *.dll/*.pyd
.
The idea is to extract all .pyd/dlls
before to zip the Lib folder, to put them into a common folder and to redirect import statement to this external folder.
I believe this can be done via sys.meta_path but I haven't succeed it.
*this package is not maintained anymore.
So my question is :
How can I redirect call to '.pyd/.dll' files that I moved outside of the zip file (without modifying the source code of modules) ?
Edit : To give you a sense of what I'm trying to do, see below my code that is supposed to catch an import statment to a specific pyd file and to redirect it to another location. At this stage I only tried on a non-zipped folder but it doesn't work...
# just test for a single pyd file that I removed from a non-zipped folder
class CustomImporter(object):
virtual_name = 'pandas._libs.tslib' # a pyd file
def find_module(self, fullname, path=None):
if fullname == self.virtual_name:
return self
return None
def load_module(self, fullname):
if fullname in sys.modules:
return sys.modules[fullname]
if fullname != self.virtual_name:
raise ImportError(fullname)
try:
path = r"C:\.....\tslib.cp35-win_amd64.pyd"
module = imp.load_dynamic("tslib",path )
module.__file__ = path
module.__loader__ = self
module.__name__ = self.virtual_name
sys.modules[self.virtual_name] = module
except BaseException as e:
raise ImportError(fullname + str(e))
return module
and it is attached as follow :
sys.meta_path.append(CustomImporter())