У меня есть библиотека 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;
}
Как передать список Python в Img_Array.Postion_Info с помощью SWIG?
Я попытался добавить карту типов в файл .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
Как мне напечатать Postion_Info * в Img_Array, не затрагивая Postion_Info снаружи?
-------- обновление 10 июня '19 ------
Спасибо за предложения @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
.Похоже, что память была освобождена перед использованием.