2

I am using Python 2.7 and trying to load a dll with ctypes:

lib = ctypes.cdll.LoadLibrary("mylib.dll")

It sometimes throws the following error, some other times it runs ok. Also with Python 3 always throws this error:

libcrypto = ctypes.cdll.LoadLibrary("data\openvpn\libeay32") File "C:\Python27\lib\ctypes__init__.py", line 440, in LoadLibrary return self._dlltype(name) File "C:\Python27\lib\ctypes__init__.py", line 362, in init self._handle = _dlopen(self._name, mode) WindowsError: [Error 487] Attempt to access invalid address

4
  • are both dll and python 32 (64) bit? Have you also tried ctypes.CDLL("data\openvpn\libeay32") ? Commented Aug 31, 2017 at 17:53
  • Yes both dll and python are on 32bit. Yes tried, the same behavior. Commented Sep 1, 2017 at 5:42
  • 1
    That's not normal. It sounds like a problem with the DLL itself, which without source we cannot attempt to fix. Commented Sep 2, 2017 at 4:36
  • Do you have any idea what this error means exactly ? Like what kind of code may cause this ? Commented Sep 4, 2017 at 5:40

1 Answer 1

3

We were having a similar issue with a FIPS-certified version of OpenSSL. Unfortunately, that version of OpenSSL is required to be loaded at a specific memory address. If you try to load OpenSSL too late when starting an application, the memory address it requires has already been taken by another dependency. The best we could figure out to "fix" this is to ensure OpenSSL (libeay32.dll) is loaded into the memory address space as soon as possible.

In your case, add the following lines AT THE TOP of your Python script (NOTE: AT THE TOP means before any other line of executable code, including import statements):

import ctypes from ctypes import cdll from ctypes.util import find_library cdll.LoadLibrary(find_library('libeay32')) 

Alternatively, you could ensure that libeay32.dll is the first dependency listed within mylib.dll.

BEGIN EDIT

While the above code helped increase the probability of success in my case, it still loaded the OpenSSL DLL too late in some instances. To fix this, I had to create a new Python wrapper executable in C++, with the following code:

#include "Python.h" #include "openssl\crypto.h" auto volatile GetVersionOpenSSL{ &SSLeay }; int wmain(size_t const argc, wchar_t const *const argv[]) { Py_Initialize(); int const result{ Py_Main(argc, const_cast<wchar_t**>(argv)) }; Py_Finalize(); return result; } 

Note that I had to take the following additional actions as well:

  1. Add libeay32.lib as the first library in the linker command line
  2. Disable the linker optimization to remove unused references

Call the resulting executable instead of python.exe with the same arguments, and that error should go away.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.