使用 Swig 传递指向缓冲区的指针导致 "TypeError"
Use Swig to pass in a pointer to a buffer results in "TypeError"
我们有一个嵌入式系统,可以对数据缓冲区执行处理。当缓冲区已满时,处理由中断触发。期望是用模拟的输入数据来测试算法。我们的数据科学团队使用 Python,算法是用 C 开发的,所以我提出为他们创建一个包装器。
问题围绕着指向传递给算法的缓冲区的指针。
作为一个简单的例子,C 函数看起来像这样:
float FakeCalc( unsigned int *dataBuffer,
float *calcSpace,
int arg1,
float arg2,
int arg3,
int arg4,
int *intermediateResults
);
我创建了一个SWIG接口文件如下:
%module fakeCalc
%include "typemaps.i"
%apply unsigned int * INPUT { unsigned int * dataBuffer };
%apply float * INOUT { float * calcSpace };
%apply int * OUTPUT { int * intermediateResults };
%{
extern float FakeCalc( unsigned int * dataBuffer,
float * calcSpace,
int winAvgSz,
float eleMulSign,
int denomWindNum,
int winSz,
int * intermediateResults
);
%}
extern float FakeCalc( unsigned int * dataBuffer,
float * calcSpace,
int winAvgSz,
float eleMulSign,
int denomWindNum,
int winSz,
int * intermediateResults
);
这会创建界面,所以我觉得我可以开始了。
在提交之前 python 中的一个简单测试实现如下所示:
#!/usr/bin/python
from numpy import zeros
from array import array
import sys
import fakeCalc
def printHelp():
print "testRun.py dataFile"
# Buffer to pass into method for scratch space
scratchBuf = zeros(10)
# Read in data to pass into method
if len(sys.argv) != 2:
printHelp()
exit()
dataFile = open(sys.argv[1], "r")
dataArr = array("I")
for dataPoint in dataFile:
dataArr.append(int(dataPoint[0:-1]))
# Run calculations
fakeCalc.FakeCalc(dataArr, scratchBuf, 10, 10.5, 10, 10)
有几点需要注意。我无法更改函数的参数,因为它是多个代码库中使用的遗留代码。缺少缓冲区大小,虽然显然不理想,但在硬件初始化时缓冲区是固定的。
calcSpace传入的buffer被算法用作scratchspace,intermediateResults内部包含一些中间步骤的结果,dataBuffer只是原始数据,没有改变。
目前我正在
TypeError: 在方法 'FakeCalc' 中,参数 1 的类型为 'unsigned int'
所以问题简而言之:
是否可以在 Python 中分配这些缓冲区并传递给 C?
在此先感谢您的帮助!
我找到了解决办法。
从python分配缓冲区并将其传入的一种简单方法是使用swig提供的'carrays'。这是一个例子:
%module processBuffer
%include "stdint.i"
%include "carrays.i"
%array_class(uint32_t, buffer);
%{
void processBuffer(unsigned int * buffer);
%}
void processBuffer(unsigned int * buffer);
在python中,创建缓冲区并按以下方式传入指针:
#!/usr/bin/python
import processBuffer
buffer = []
for x in range (0, 10):
buffer.append(x)
print buffer
test = processBuffer.buffer(10);
for x in range (0, 10):
test[x] = buffer[x]
processBuffer.processBuffer(test.cast())
到目前为止,这种方法没有问题。
对于感兴趣的人的一些背景,查看生成的代码,原来的问题就变得很清楚了。传入指针 SWIG 假设正在传递单个对象。为此,将创建一个临时对象以避免类型不兼容。这分解了数组。有更复杂的解决方案也可以创建自定义类型映射,但上述解决方案要简单得多。
我们有一个嵌入式系统,可以对数据缓冲区执行处理。当缓冲区已满时,处理由中断触发。期望是用模拟的输入数据来测试算法。我们的数据科学团队使用 Python,算法是用 C 开发的,所以我提出为他们创建一个包装器。
问题围绕着指向传递给算法的缓冲区的指针。
作为一个简单的例子,C 函数看起来像这样:
float FakeCalc( unsigned int *dataBuffer,
float *calcSpace,
int arg1,
float arg2,
int arg3,
int arg4,
int *intermediateResults
);
我创建了一个SWIG接口文件如下:
%module fakeCalc
%include "typemaps.i"
%apply unsigned int * INPUT { unsigned int * dataBuffer };
%apply float * INOUT { float * calcSpace };
%apply int * OUTPUT { int * intermediateResults };
%{
extern float FakeCalc( unsigned int * dataBuffer,
float * calcSpace,
int winAvgSz,
float eleMulSign,
int denomWindNum,
int winSz,
int * intermediateResults
);
%}
extern float FakeCalc( unsigned int * dataBuffer,
float * calcSpace,
int winAvgSz,
float eleMulSign,
int denomWindNum,
int winSz,
int * intermediateResults
);
这会创建界面,所以我觉得我可以开始了。
在提交之前 python 中的一个简单测试实现如下所示:
#!/usr/bin/python
from numpy import zeros
from array import array
import sys
import fakeCalc
def printHelp():
print "testRun.py dataFile"
# Buffer to pass into method for scratch space
scratchBuf = zeros(10)
# Read in data to pass into method
if len(sys.argv) != 2:
printHelp()
exit()
dataFile = open(sys.argv[1], "r")
dataArr = array("I")
for dataPoint in dataFile:
dataArr.append(int(dataPoint[0:-1]))
# Run calculations
fakeCalc.FakeCalc(dataArr, scratchBuf, 10, 10.5, 10, 10)
有几点需要注意。我无法更改函数的参数,因为它是多个代码库中使用的遗留代码。缺少缓冲区大小,虽然显然不理想,但在硬件初始化时缓冲区是固定的。
calcSpace传入的buffer被算法用作scratchspace,intermediateResults内部包含一些中间步骤的结果,dataBuffer只是原始数据,没有改变。
目前我正在 TypeError: 在方法 'FakeCalc' 中,参数 1 的类型为 'unsigned int'
所以问题简而言之: 是否可以在 Python 中分配这些缓冲区并传递给 C?
在此先感谢您的帮助!
我找到了解决办法。
从python分配缓冲区并将其传入的一种简单方法是使用swig提供的'carrays'。这是一个例子:
%module processBuffer
%include "stdint.i"
%include "carrays.i"
%array_class(uint32_t, buffer);
%{
void processBuffer(unsigned int * buffer);
%}
void processBuffer(unsigned int * buffer);
在python中,创建缓冲区并按以下方式传入指针:
#!/usr/bin/python
import processBuffer
buffer = []
for x in range (0, 10):
buffer.append(x)
print buffer
test = processBuffer.buffer(10);
for x in range (0, 10):
test[x] = buffer[x]
processBuffer.processBuffer(test.cast())
到目前为止,这种方法没有问题。
对于感兴趣的人的一些背景,查看生成的代码,原来的问题就变得很清楚了。传入指针 SWIG 假设正在传递单个对象。为此,将创建一个临时对象以避免类型不兼容。这分解了数组。有更复杂的解决方案也可以创建自定义类型映射,但上述解决方案要简单得多。