将ByteArray从Python传递给C函数

时间:2017-07-15 12:20:28

标签: python c ctypes

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

/* 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)

但是在将第一个参数(MyData)传递给C函数时出现类型错误。

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

奥利弗

1 个答案:

答案 0 :(得分:1)

我假设ByteArray应该是bytearray。我们可以使用create_string_buffer创建一个可变字符缓冲区,它是ctypes 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')