我有一个无法修改的c ++库,它在另一个结构中有一个结构数组。我得到的相关代码如下:
typedef int Landmark_Type[10];
typedef int Rect_Type;
typedef int Img_Num_Type;
struct Rect{
Rect_Type left;
Rect_Type top;
Rect_Type width;
Rect_Type height;
};
struct Postion_Info{
Landmark_Type landmark;
Rect location;
};
struct Img_Array{
Img_Num_Type imgNum;
Postion_Info *imgInfo;
};
int get_postion(Postion_Info PosInfo) {
printf("left:\t%d\n", PosInfo.location.left);
printf("top:\t%d\n", PosInfo.location.top);
printf("width:\t%d\n", PosInfo.location.width);
printf("height:\t%d\n", PosInfo.location.height);
for (int i = 0; i < 10; ++i) {
printf("landmark %d:\t%d\n", i, PosInfo.landmark[i]);
}
return 0;
}
int get_img_array(Img_Array imgarray){
printf("imgNum:\t%d\n", imgarray.imgNum);
for (int i =0; i < imgarray.imgNum; i++) {
get_postion(imgarray.imgInfo[i]);
}
return 0;
}
如何通过SWIG将python列表传递给Img_Array.Postion_Info?
我尝试如下向.i文件添加类型映射:
%typemap(in) Postion_Info *(std::vector<Postion_Info> temp) {
if (PyList_Check($input)) {
const size_t size = PyList_Size($input);
temp.resize(size);
for (int i = 0; i < size; ++i) {
void *argp = 0 ;
const int res = SWIG_ConvertPtr(PyList_GetItem($input, i), &argp, $*1_descriptor, 0);
if (!SWIG_IsOK(res)) {
SWIG_exception_fail(SWIG_ArgError(res), "in method '" "$symname" "', argument " "$argnum"" of type '" "$1_type""'");
}
temp[i] = *reinterpret_cast<Postion_Info *>(argp);
}
$1 = &temp[0];
}
else {
// Raise exception
SWIG_exception_fail(SWIG_TypeError, "Expected list in $symname");
}
}
和python文件为:
posinfo = Postion_Info()
posinfo.landmark = landmark
posinfo.location = location
posinfo2 = Postion_Info()
posinfo2.landmark = landmark2
posinfo2.location = location2
imgarray = Img_Array()
imgarray.imgNum = 2
imgarray.imgInfo = [posinfo,posinfo2]
但是出现了错误:
posinfo.landmark = landmark
TypeError: Expected list in Postion_Info_landmark_set
Exception ignored in: <built-in function delete_Postion_Info>
TypeError: Expected list in delete_Postion_Info
如何在Img_Array中键入映射Postion_Info *而不影响外部的Postion_Info?
--------更新19年6月10日------
谢谢@JensMunk的建议。
我修改了.i文件:
%inline %{
Img_Array set_img_array(Img_Num_Type imgNum, Postion_Info *imgInfo){
Img_Array img_array;
img_array.imgNum = imgNum;
img_array.imgInfo = imgInfo;
return img_array;
}
%}
%typemap(in) (Img_Num_Type imgNum, Postion_Info *imgInfo) {
int i;
if (!PyList_Check($input)) {
PyErr_SetString(PyExc_ValueError, "Expecting a list");
SWIG_fail;
}
$1 = PyList_Size($input);
Postion_Info *temp = (Postion_Info *) malloc($1*sizeof(Postion_Info));
for (i = 0; i < $1; i++) {
void *argp = 0 ;
const int res = SWIG_ConvertPtr(PyList_GetItem($input, i), &argp, $2_descriptor, 0);
if (!SWIG_IsOK(res)) {
SWIG_exception_fail(SWIG_ArgError(res), "in method '" "$symname" "', argument " "$argnum"" of type '" "$2_type""'");
}
temp[i] = *reinterpret_cast<Postion_Info *>(argp);
}
$2 = &temp[0];
}
%typemap(freearg) (Img_Num_Type imgNum, Postion_Info *imgInfo) {
if ($2) free($2);
}
在python
中imgarray = set_img_array([posinfo, posinfo2])
ret = get_img_array(imgarray)
但是我发现landmark[0]~[4]
中的imgarray.imgInfo[0]
已被更改,因为它们在%typemap
之后仍然正确。看来该内存已在使用前释放。