Python ctypes - 获取 CFUNCTYPE 的名称

Dan*_*Bak 3 python dll ctypes

我正在研究一些我没有用 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>}
Run Code Online (Sandbox Code Playgroud)

我是否可以找到 self.function 的定义位置,或者函数的名称是什么?self.function._objects 指向 DLL,但我不清楚如何或是否可以找到该函数的名称,以便我可以在源代码中查找它。

此外,是否可以在调用函数时单步执行该函数?代码中的调用方式如下:

self.function(*self.args)
Run Code Online (Sandbox Code Playgroud)

aba*_*ert 5

\n

我是否可以找到 self.function 的定义位置,

\n
\n\n

不,因为它是在一些用 C(或其他语言)编写的源代码中定义的,而您甚至没有(或者也许您有,但 Python 不知道它在哪里);你所拥有的只是编译它所产生的 DLL/so/dylib 。

\n\n
\n\n
\n

\xe2\x80\xa6\xc2\xa0 或者函数的名称是什么?

\n
\n\n

是的。通常,您可以像 Python 中的许多其他对象一样获取 ctypes C 函数的名称:通过__name__特殊属性:

\n\n
>>> import ctypes\n>>> libm = ctypes.CDLL(\'libm.dylib\')\n>>> fabs = libm.fabs\n>>> fabs\n<_FuncPtr object at 0x1067ac750>\n>>> fabs.__name__\n\'fabs\'\n
Run Code Online (Sandbox Code Playgroud)\n\n
\n

self.function._objects 指向 DLL,但我不清楚如何或是否可以找到该函数的名称,以便可以在源代码中查找它。

\n
\n\n

您无法从那里获取函数名称。但您可以通过属性从那里获取库名称_name

\n\n
>>> fabs._objects[\'0\']._name\n\'libm.dylib\'\n
Run Code Online (Sandbox Code Playgroud)\n\n

(尽管有下划线,但正如文档所解释的那样,这是一个公共属性。)

\n\n

CDLL这通常是传递给构造函数或调用的名称cdll.LoadLibrary。在 Windows 上,对于加载了cdll.spam魔法的库,我认为您实际上获得了解析的路径名,例如\'D:\\path\\to\\spam.dll\',而不仅仅是\'spam\'\'spam.dll\',但我并不肯定。

\n\n
\n\n
\n

此外,是否可以在调用函数时单步执行该函数?

\n
\n\n

不是,因为该函数是编译后的机器代码;它没有任何 Python 字节码供您进入。

\n\n

当然,您可以附加 Visual Studio、lldb 或 gdb 等调试器,并以这种方式单步执行机器代码。

\n