Python ctypes - получить имя CFUNCTYPE - PullRequest
0 голосов
/ 12 сентября 2018

Я смотрю код, который я не написал с помощью 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>}

Можно ли мне узнать, где была определена функция self.function, или как называется функция? self.function._objects указывает на DLL, но мне неясно, как или если я могу найти имя функции, чтобы найти его в исходном коде.

Кроме того, возможно ли войти в функцию при ее вызове? Он вызывается в коде следующим образом:

self.function(*self.args)

1 Ответ

0 голосов
/ 12 сентября 2018

Могу ли я узнать, где была определена собственная функция,

Нет, потому что он был определен в некотором исходном коде, написанном на C (или другом языке), которого у вас даже нет (или, может быть, у вас есть, но Python не знает, где он находится); все, что у вас есть, это DLL / so / dylib, которая возникла в результате его компиляции.


… или как называется функция?

Да. Обычно вы можете получить имя функции Ctypes C так же, как и многие другие объекты в Python: через специальный атрибут __name__:

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

self.function._objects указывает на DLL, но мне неясно, как или если я могу найти имя функции, чтобы найти его в исходном коде.

Вы не можете получить имя функции оттуда. Но вы можете получить имя библиотеки оттуда через атрибут _name:

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

(Несмотря на подчеркивание, это открытый атрибут, как объясняют документы.)

Обычно это имя передается конструктору CDLL или вызову cdll.LoadLibrary. В Windows для библиотек, загруженных с помощью волшебства cdll.spam, я думаю, что вы на самом деле получите разрешенный путь, например 'D:\path\to\spam.dll', а не просто 'spam' или 'spam.dll', но я не уверен.


Кроме того, возможно ли войти в функцию при ее вызове?

Нет, поскольку функция представляет собой скомпилированный машинный код; он не имеет никакого байт-кода Python для вас.

Конечно, вы можете подключить отладчик, такой как Visual Studio, lldb или gdb, и войти в машинный код таким образом .

...