Daniel Paczuski Bak
Daniel Paczuski Bak

Reputation: 4088

Python ctypes - get name of CFUNCTYPE

I am looking into some code I have not written with pdb.

(Pdb) self.function
<CFunctionType object at 0x000000DC768E0E18>
(Pdb) type(self.function)
<class 'ctypes.CFUNCTYPE.<locals>.CFunctionType'>
(Pdb) dir(self.function)
['__bool__', '__call__', '__class__', '__ctypes_from_outparam__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_argtypes_', '_b_base_', '_b_needsfree_', '_flags_', '_objects', '_restype_', 'argtypes', 'errcheck', 'restype']
(Pdb) self.function._flags_
1
(Pdb) self.function._objects
{'0': <CDLL 'C:\path', handle 7ffe26465400 at 0xdc74ad2908>}

Is it possible for me to find out where self.function was defined, or what the name of the function is? self.function._objects points towards a DLL, but it's not clear to me how or if I can find the function's name so I can look it up in the source code.

Further, is it possible to step into the function when it is called? It is called in the code in the following way:

self.function(*self.args)

Upvotes: 3

Views: 877

Answers (1)

abarnert
abarnert

Reputation: 366013

Is it possible for me to find out where self.function was defined,

No, because it was defined in some source code written in C (or another language) that you don't even have (or maybe you do, but Python has no idea where it is); all you have is the DLL/so/dylib that resulted from compiling it.


… or what the name of the function is?

Yes. You can usually get the name of a ctypes C function the same way as many other objects in Python: via the __name__ special attribute:

>>> import ctypes
>>> libm = ctypes.CDLL('libm.dylib')
>>> fabs = libm.fabs
>>> fabs
<_FuncPtr object at 0x1067ac750>
>>> fabs.__name__
'fabs'

self.function._objects points towards a DLL, but it's not clear to me how or if I can find the function's name so I can look it up in the source code.

You can't get the function name from there. But you can get the library name from there via the _name attribute:

>>> fabs._objects['0']._name
'libm.dylib'

(Despite the underscore, this is a public attribute, as the docs explain.)

This will usually be the name passed to the CDLL constructor or cdll.LoadLibrary call. On Windows, for libraries loaded with the cdll.spam magic, I think you actually get the resolved pathname, like 'D:\path\to\spam.dll', not just 'spam' or 'spam.dll', but I'm not positive.


Further, is it possible to step into the function when it is called?

No, because the function is compiled machine code; it doesn't have any Python bytecode for you to step into.

You could, of course, attach a debugger like Visual Studio, lldb, or gdb and step into the machine code that way.

Upvotes: 5

Related Questions