我使用swig挣扎于python的c ++包装,让我卡住的是输出参数char **(char *列表)的输出参数。
我的c ++是这样的:
class dict{
int getKeys(const char **&keys, int &result_length)
}
我知道我需要使用typemap,而且我在swig接口文件(.i)中写道:
%{
#include "dict.hpp"
%}
%apply int &OUTPUT { int & };
%typemap(in, numinputs=0) char **& (char **temp) {
$1 = &temp;
}
%typemap(argout) char**& %{
int ntokens;
int itoken;
for (ntokens = 0; *$1[ntokens] != NULL; ntokens++) {
}
PyObject* temp = NULL;
temp = $result;
$result = PyList_New(ntokens);
for (itoken = 0; itoken < ntokens; itoken++) {
PyList_Append($result, PyUnicode_FromString( *$1[itoken] ));
}
PyObject* list_temp = NULL;
list_temp = $result;
$result = PyList_New(1);
PyList_SetItem($result, 0, temp);
PyList_Append($result, list_temp);
Py_DECREF(temp);
Py_DECREF(list_temp);
%}
%typemap(freearg) char**& %{
free(*$1);
%}
%include "dict.hpp"
编译.i文件时没问题,但是当我在python中使用它时, python.exe已停止工作
resultCode, keys, keysCount = dict.getkeys()
我通过引用char *来成功包装输出参数:
%typemap(in, numinputs=0) char *& (char *temp) {
$1 = &temp;
}
%typemap(argout) char*& %{
PyObject* temp = NULL;
temp = $result;
$result = PyList_New(1);
PyList_SetItem($result, 0, temp);
PyList_Append($result, PyUnicode_FromString(*$1));
Py_DECREF(temp);
%}
%typemap(freearg) char*& %{
free(*$1);
%}
但是如何通过引用char **(char *列表)来包装输出参数?有人可以帮忙吗?
答案 0 :(得分:0)
这一行有一个问题:
PyList_Append($result, PyUnicode_FromString( *$1[itoken] ));
应该是:
PyList_Append($result, PyUnicode_FromString( (*$1)[itoken] ));
$result
处理看起来很有趣,但我没有继续调试。我认为更好的解决方案是使用多参数类型映射。以下是我提出的测试方法(Windows操作系统):
<强> dict.hpp 强>
#ifdef EXPORTS
# define API __declspec(dllexport)
#else
# define API __declspec(dllimport)
#endif
API void getKeys(const char **& keys, int& result_length);
<强> dict.cpp 强>
#define EXPORTS
#include "dict.hpp"
API void getKeys(const char **& keys, int& result_length)
{
result_length = 5;
keys = new const char*[result_length];
keys[0] = "abcd";
keys[1] = "efgh";
keys[2] = "ijkl";
keys[3] = "mnop";
keys[4] = "qrst";
}
<强> dict.i 强>
%module dict
%{
#include "dict.hpp"
%}
%include <windows.i>
%typemap(in,numinputs=0) (const char**& keys,int& result_length) (char **temp, int len) %{
$1 = &temp;
$2 = &len;
%}
%typemap(argout) (const char**& keys,int& result_length) (PyObject* obj) %{
obj = PyList_New(*$2);
for (int itoken = 0; itoken < *$2; itoken++) {
PyList_SET_ITEM(obj, itoken, PyUnicode_FromString( (*$1)[itoken] ));
}
$result = SWIG_Python_AppendOutput($result,obj);
%}
%typemap(freearg) (const char**& keys,int& result_length) %{
delete [] *$1;
%}
%include "dict.hpp"
输出:
Python 3.6.3 (v3.6.3:2c5fed8, Oct 3 2017, 18:11:49) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import dict
>>> dict.getKeys()
['abcd', 'efgh', 'ijkl', 'mnop', 'qrst']