尝试freearg
类型映射:
%typemap(freearg) DataWrap *buff {
delete $1->data;
}
另外,你有delete $1;
. 应该是delete $1->data
吗?
编辑
我在处理这个问题时发现了另一个可能与您的问题有关的问题。如果您在 Windows 上并且您的实现fun1
在与 SWIG 包装器代码不同的 DLL 中,请确保使两个 DLL 链接到同一个 C 运行时 DLL(/MD
例如,通过 Microsoft VC++ 中的编译器开关),因为内存会然后在一个DLL中分配(new
我假设)并在另一个DLL中释放。
这是我正在玩的代码。它可能会帮助你。它还包括一个用于消除从 Python 发送字符串和大小的类型映射和一个用于生成临时 DataWrap 对象的类型映射,因此它也不必传递。在实现文件x.cpp
中,我伪造了一个将字符串转换为 UTF16 的实现,该实现仅适用于简单的 ASCII 字符串。
另请注意,我在不使用类型映射的情况下让它工作freearg
,尽管使用类型映射也对我有用。
生成文件
_x.pyd: x_wrap.cxx x.dll
cl /MD /nologo /LD /Zi /EHsc /W4 x_wrap.cxx /Id:\dev\python27\include -link /LIBPATH:d:\dev\python27\libs /OUT:_x.pyd x.lib
x.dll: x.cpp x.h
cl /MD /nologo /Zi /LD /EHsc /W4 x.cpp
x_wrap.cxx: x.h x.i
swig -python -c++ x.i
十一
%module x
%begin %{
#pragma warning(disable:4127 4211 4706)
%}
%{
#include "x.h"
%}
%include <windows.i>
%typemap(in) (const char *szInBuffer,unsigned int inSize) {
if (!PyString_Check($input)) {
PyErr_SetString(PyExc_ValueError, "Expecting a string");
return NULL;
}
$1 = PyString_AsString($input);
$2 = PyString_Size($input);
}
%typemap(in, numinputs=0) DataWrap* buff (DataWrap temp) {
$1 = &temp;
}
%typemap(argout) DataWrap* buff {
int byteorder = -1;
$result = PyUnicode_DecodeUTF16((const char*)($1->data), ($1->size)*sizeof(wchar_t), NULL, &byteorder);
delete [] $1->data;
}
%include "x.h"
xh
#ifdef API_EXPORTS
# define API __declspec(dllexport)
#else
# define API __declspec(dllimport)
#endif
struct DataWrap
{
wchar_t* data;
int size;
};
extern "C" API void fun1(const char* szInBuffer, unsigned int inSize, DataWrap* buff);
x.cpp
#include <stdlib.h>
#define API_EXPORTS
#include "x.h"
API void fun1(const char* szInBuffer, unsigned int inSize, DataWrap* buff)
{
unsigned int i;
buff->size = inSize;
buff->data = new wchar_t[inSize];
for(i = 0; i < inSize; i++)
buff->data[i] = szInBuffer[i];
}
输出
Python 2.7.3 (default, Apr 10 2012, 23:31:26) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import x
>>> x.fun1('abc')
u'abc'