2017-07-15 281 views
1

我想将Python程序中的ByteArray变量传递给我用C编写的DLL,以便加速某些特定的处理,这些处理在Python中速度太慢。我已经通过网络,尝试了与C#参数组合,byref,cast,memoryviews,addressof,但没有任何作用。有没有简单的方法来实现这一点,而不是将我的ByteArray复制到其他将会通过的东西? 这里就是我想要做:将ByteArray从Python传递到C函数

/* My C DLL */ 
__declspec(dllexport) bool FastProc(char *P, int L) 
{ 
    /* Do some complex processing on the char buffer */ 
    ; 
    return true; 
} 

# My Python program 
from ctypes import * 
def main(argv): 
    MyData = ByteArray([1,2,3,4,5,6]) 
    dll = CDLL('CHELPER.dll') 
    dll.FastProc.argtypes = (c_char_p, c_int) 
    dll.FastProc.restype = c_bool 

    Result = dll.FastProc(MyData, len(MyData)) 
    print(Result) 

但传递的第一个参数(迈德特)C函数时,我得到一个类型错误。

是否有任何解决方案不需要太多的开销会浪费我的C函数的好处?

奥利维尔

+0

什么是'ByteArray'?它不应该是'bytearray'(全部小写)吗?你在使用Python 3吗? –

+0

是它的一个字节数组,对于输入错误 – Marmotte06

+0

创建一个长度相同的ctypes数组类型,并将'bytearray'传递给它的['from_buffer'](https://docs.python.org/3/library/ctypes。 html#ctypes._CData.from_buffer)contsructor,例如'L = len(MyData);''P =(ctypes.c_char * L).from_buffer(MyData);''dll.FastProc(P,L)'。 – eryksun

回答

0

我假设ByteArray应该是bytearray。我们可以使用create_string_buffer来创建一个可变字符缓冲区,它是一个​​数组c_char。但create_string_buffer不是接受bytearray,我们需要传递一个bytes对象来初始化它;幸运的是,bytesbytearray之间的投射是快速且高效的。

我没有你的DLL,因此为了测试数组的行为是否正确,我将使用libc.strfry函数来混洗它的字符。

from ctypes import CDLL, create_string_buffer 

libc = CDLL("libc.so.6") 

# Some test data, NUL-terminated so we can safely pass it to a str function. 
mydata = bytearray([65, 66, 67, 68, 69, 70, 0]) 
print(mydata) 

# Convert the Python bytearray to a C array of char 
p = create_string_buffer(bytes(mydata), len(mydata)) 

#Shuffle the bytes before the NUL terminator byte, in-place. 
libc.strfry(p) 

# Convert the modified C array back to a Python bytearray 
newdata = bytearray(p.raw) 
print(newdata) 

典型输出

bytearray(b'ABCDEF\x00') 
bytearray(b'BFDACE\x00') 
+0

嗯,乍一看我以为你已经找到了解决方案,但我去了create_string_buffer的文档,我的理解是它创建了一个新对象,并拷贝了它原来的bytearray。这就是为什么在最后你打印新数据而不是mydata。我更喜欢迄今为止,我的函数就地工作原始字节数组,没有任何复制。字节数是可变的,不应该违反Python法则。我发现帖子建议SWIG达到我想要的,我需要深入了解这一点。非常感谢您的帮助,我发现了create_string_buffer函数 – Marmotte06