5

I'm trying to get libarchive module working in python 3.4 on windows. I've installed libarchive-c with pip and all went ok but whenever I try to import it into my code or even to run it alone I'me getting error:

OSError: [WinError 126] The specified module could not be found

This is coming from ffi.py from the code below:

libarchive_path = os.environ.get('LIBARCHIVE') or find_library('archive') 
libarchive = ctypes.cdll.LoadLibrary(libarchive_path)

I've never used ctypes before but if I understand correctly it is looking for external DLL. So found and installed http://gnuwin32.sourceforge.net/packages/libarchive.htm also I've added C:\Program Files (x86)\GnuWin32\bin to my %PATH% in environmental variables but it still cannot load the module. As it does not give me the name I'm not sure what module it is looking for. What am I missing?

NosIreland
  • 91
  • 2
  • 8
  • It's looking for either the DLL name from the `LIBARCHIVE` environment variable or "archive.dll". I suggest using `LIBARCHIVE` instead of renaming the DLL. You can test this in the command prompt using `set LIBARCHIVE=libarchive2.dll` before running Python. Note that this is a 32-bit DLL, so you'll have to use 32-bit Python. – Eryk Sun May 11 '16 at 21:57

1 Answers1

6

(disclaimer) I contribute to https://github.com/Changaco/python-libarchive-c and I maintain https://github.com/nexB/scancode-toolkit

Both contain a ctypes binding for libarchive, though ScanCode is for extraction only.

My answer here is for python-libarchive-c, but ScanCode contains some of the DLL you are looking for so I am lacing in a bit of both.

To get python-libarchive-c going on Windows you need a libarchive DLL and its deps that can then be loaded.

There are no pre-built DLLs bundled in python-libarchive-c but I have prebuilt Windows binaries for another project here: https://github.com/nexB/scancode-toolkit/tree/develop/src/extractcode/bin/win-32/bin The corresponding source code is there: https://github.com/nexB/scancode-thirdparty-src And you have MinGW32 build instructions there if you want to rebuild from source yourself: https://github.com/nexB/scancode-thirdparty-src/blob/master/libarchive/build.sh#L47

In general to load a DLL from a path -- assuming that the var libarchive contains the full path to that DLL -- use this: lib = ctypes.CDLL(libarchive) Now this is for Scancode. For python-libarchive-c, you could try to set the LIBARCHIVE variable to point the path of your DLL with: set LIBARCHIVE="C:\.....\libarchive.dll"

Then start Python, import the library and use it.

NB: I did not test this (yet) , but this should work. IF not please file a bug. I did not run any test on Python 3.4 either. I use primarily Python 2.7. But the DLL and the code is not Python 2.7-specific at all.

FWIW, the way scancode loads the library is a tad more engaged since it can from the same code load DLLs Win/Linux/Mac for specific 32 or 64 bits archs using conventional locations. You can see the code in action there: https://github.com/nexB/scancode-toolkit/blob/develop/src/extractcode/libarchive2.py#L64

ScanCode is NOT using python-libarchive-c ATM yet but a different/custom ctypes binding focused on a more specific use case of extraction only. At least it gives you access to a Win DLL and its deps (or instruction a build them) and an example on how to load it correctly.

/HTH

Philippe Ombredanne
  • 2,017
  • 21
  • 36
  • ***I*** tried it, but the libarchive module still will not find the libarchive.DLL - even though I set LIBARCHIVE variable in cmd.exe – Prof. Falken Feb 16 '17 at 13:09
  • 1
    I had to change the code in the module: `if _FILEPATH == '': _FILEPATH = ctypes.util.find_library('libarchive') if _FILEPATH is None: _FILEPATH = 'libarchive.dll'` <-- *to* ***.dll*** *instead of* ***.so*** – Prof. Falken Feb 16 '17 at 13:17
  • Besides, this seems to work under windows without patching (but we still need the DLLs of course) https://github.com/Changaco/python-libarchive-c – Prof. Falken Feb 16 '17 at 13:25