Strange Python ctypes behavior. Always loads the m (math) library

AstrOne

Can someone explain to me why the following Python code works?

import ctypes
import ctypes.util

boblib = ctypes.cdll.LoadLibrary(ctypes.util.find_library("bob_is_your_uncle"))
boblib.cos.argtypes = [ctypes.c_double]
boblib.cos.restype = ctypes.c_double
print(boblib.cos(0)) # This prints out "1.0"

I am 1000% sure that there is no "bob_is_your_uncle" library on my filesystem. Yet, it seems like ctypes loads the m library. Why is this happening?

Also, if I do this: print(boblib), I get this:

<CDLL 'None', handle 7f6a80f6d170 at 0x7f6a7f34d0b8>

What does CDLL 'None' mean?

Thanks in advance.

PS: Doing a --version on both my Python interpreters I get: Python 3.6.5rc1 and Python 2.7.14+. The above code gives the same result on both versions. My OS is Debian (Testing repo).

user2357112 supports Monica

It's not loading the math library. It appears to be loading the Python executable itself, which has cos linked in.

There is indeed no library named bob_is_your_uncle, so find_library returns None. (That's where the None comes from in the output you're seeing.)

On Unix, the LoadLibrary logic has a specific check that translates a None name to a null pointer for the underlying dlopen routine. dlopen has special handling for a null name:

If filename is NULL, then the returned handle is for the main program.

In fact, on Unix, ctypes.pythonapi is created as

pythonapi = PyDLL(None)

explaining why the None handling is there in the first place. The CDLL object you've created is almost like ctypes.pythonapi, except that it doesn't hold the GIL for function calls or check for exceptions (because CDLL instead of PyDLL), so it's useless for interacting with the actual C Python API.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related