Python 当我使用带有动态fn名称的Ctypes时,为什么会得到负ptr?
我有一个下面的python脚本可以工作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
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
但是发生的错误不止这些。。。