Python 当我使用带有动态fn名称的Ctypes时,为什么会得到负ptr?

Python 当我使用带有动态fn名称的Ctypes时,为什么会得到负ptr?,python,ctypes,Python,Ctypes,我有一个下面的python脚本可以工作 from ctypes import c_uint32, c_uint8, c_void_p, c_char_p lib = ctypes.cdll.LoadLibrary(dll_dir_name + "my_dll.dll") lib.my_func.argtype = c_char_p lib.my_func.restype = c_void_p ptr = lib.my_func("Hello".encode

我有一个下面的python脚本可以工作

from ctypes import c_uint32, c_uint8, c_void_p, c_char_p
lib = ctypes.cdll.LoadLibrary(dll_dir_name + "my_dll.dll")
lib.my_func.argtype = c_char_p
lib.my_func.restype = c_void_p
ptr = lib.my_func("Hello".encode('utf-8'))
ptr
# ptr is positive value and below command works
raw_json = ctypes.cast(ptr, c_char_p).value.decode('utf-8')
但是,当我使用fn name作为变量时,python正在崩溃

from ctypes import c_uint32, c_uint8, c_void_p, c_char_p
lib = ctypes.cdll.LoadLibrary(dll_dir_name + "my_dll.dll")
fn_name = "my_func"
lib[fn_name].argtype = c_char_p
lib[fn_name].restype = c_void_p
ptr = lib[fn_name]("Hello".encode('utf-8'))
ptr
# ptr is negative value and command crashes python
raw_json = ctypes.cast(ptr, c_char_p).value.decode('utf-8')

原因是每次使用
lib[fn\u name]
时,它都会返回一个不同的
\u FuncPtr
实例。如果没有正确的
.argtypes
(复数)和
.restype
(单数),我将使用以下C代码处理ctypes:

测试c:

__declspec(dllexport)             // Needed for Windows...
API double func(double a) {
    return a * 1.5;
}
例如:

>>> from ctypes import *
>>> dll = CDLL('test')
>>> 'func' in dir(dll)     # attribute doesn't exist yet
False
>>> dll.func               # attribute is created caching a single _FuncPtr instance.
<_FuncPtr object at 0x0000018455E00798>
>>> 'func' in dir(dll)
True
>>> dll.func               # fetches the same instance (same address)
<_FuncPtr object at 0x0000018455E00798>  
>>> dll['func']            # Creates a new _FuncPtr instance each time
<_FuncPtr object at 0x0000018455E00868>
>>> dll['func']            # different
<_FuncPtr object at 0x0000018455E00938>
>>> dll['func']            # different
<_FuncPtr object at 0x0000018455E00A08>
输出:

Traceback (most recent call last):
  File "C:\test.py", line 8, in <module>
    print(dll[f](2.5))
ctypes.ArgumentError: argument 1: <class 'TypeError'>: Don't know how to convert parameter 1
3.75
3.75
输出:

Traceback (most recent call last):
  File "C:\test.py", line 8, in <module>
    print(dll[f](2.5))
ctypes.ArgumentError: argument 1: <class 'TypeError'>: Don't know how to convert parameter 1
3.75
3.75
另一个选项是使用
getattr()
,它查找并缓存命名属性,以便将来的调用返回相同的地址:

>>> from ctypes import *
>>> dll = CDLL('test')
>>> 'func' in dir(dll)   # attribute doesn't exist
False
>>> f = 'func'
>>> getattr(dll,f)  # look up attribute by name
<_FuncPtr object at 0x0000028171EE0798>
>>> 'func' in dir(dll)   # attribute exists
True
>>> getattr(dll,f)       # looks up cached attribute.
<_FuncPtr object at 0x0000028171EE0798>
输出:

Traceback (most recent call last):
  File "C:\test.py", line 8, in <module>
    print(dll[f](2.5))
ctypes.ArgumentError: argument 1: <class 'TypeError'>: Don't know how to convert parameter 1
3.75
3.75

但是仍然可以简单地使用
f=getattr(dll,'func')
一次,并使用
f
而不是多次查找。

。argtypes
不是
。argtype
但是发生的错误不止这些。。。