SWIG将Python列表转换为char **示例失败



我正在遵循SWIG教程,我目前正在学习:&;32.9.1将Python列表转换为字符**&;。这个示例在我的机器上返回malloc错误:

import example  
example.print_args(["a","bc","dc"])

python(57911,0x10bd32e00) malloc: ***错误的对象0x7f7ee0406b90:指针被释放未分配Python (57911,0x10bd32e00) malloc: ***在malloc_error_break中设置一个断点进行调试157911中止python1 57911 abort python

这个错误是意料之外的,因为这正是教程提供的代码。欢迎任何帮助!提前感谢

规格:

  • MacOS Big Sur
  • Python 3.8
  • c++ 17

这是我的setup.py(整个存档的可重复性):

#!/usr/bin/env python
"""
setup.py file for SWIG example
"""
from distutils.core import setup, Extension
import os
import sys
import glob
# gather up all the source files
srcFiles = ['example.i']
includeDirs = []
srcDir = os.path.abspath('src')
for root, dirnames, filenames in os.walk(srcDir):
for dirname in dirnames:
absPath = os.path.join(root, dirname)
globStr = "%s/*.c*" % absPath
files = glob.glob(globStr)
includeDirs.append(absPath)
srcFiles += files
extra_args = ['-stdlib=libc++', '-mmacosx-version-min=10.7', '-std=c++17', '-fno-rtti']
os.environ["CC"] = 'clang++'
#
example_module = Extension('_example',
srcFiles,  # + ['example.cpp'], # ['example_wrap.cxx', 'example.cpp'],
include_dirs=includeDirs,
swig_opts=['-c++'],
extra_compile_args=extra_args,
)
setup(name='example',
version='0.1',
author="SWIG Docs",
description="""Simple swig example from docs""",
ext_modules=[example_module],
py_modules=["example"],
)

示例代码可以在Python 2中工作,但有一个错误以及Python 3的语法更改。char**必须传递字节字符串,这是Python 2中使用"string"语法时的默认值,但需要一个前导b,例如Python 3中的b"string"

如此:

import example  
example.print_args([b"a",b"bc",b"dc"])

崩溃是由于一个错误调用free两次,如果一个不正确的参数类型被发现。对示例进行以下更改:

if (PyString_Check(o)) {
$1[i] = PyString_AsString(PyList_GetItem($input, i));
} else {
//free($1); // REMOVE THIS FREE
PyErr_SetString(PyExc_TypeError, "list must contain strings");
SWIG_fail;

SWIG_fail;最终调用freearg类型映射,后者第二次调用free。通过此更改,如果传递不正确的参数,例如非列表或Unicode字符串而不是字节字符串,您应该看到以下内容:

>>> import argv
>>> argv.print_args(1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:argv.py", line 66, in print_args
return _argv.print_args(argv)
TypeError: not a list
>>> argv.print_args(['abc','def'])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:argv.py", line 66, in print_args
return _argv.print_args(argv)
TypeError: list must contain strings
>>> argv.print_args([b'abc',b'def'])
argv[0] = abc
argv[1] = def
2

将错误信息更改为"list必须包含bytestring "也会有帮助😊

相关内容

最新更新