- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试了解 SWIG 的工作原理。假设我有这个简单的 Foo-Bar 类:
#include <vector>
class Bar {
public:
Bar();
~Bar();
int bar_data;
};
class Foo {
public:
// does not take ownership.
Foo(std::vector<Bar>* b) { b_ = b; }
private:
std::vector<Bar>* b_;
};
假设我传递给 Foo 的 vector 很大,所以我不想复制它,只复制指针。在我的 C++ 应用程序中,我将确保注入(inject)到 Foo 的参数(即 b)比我用它创建的 Foo 实例长寿。我如何在 SWIG for python 中执行此操作?我试着写我的类型图(我想我可以使用模板,但这能解决问题吗?我想使用类型图来理解它)。这是 swig 文件:
%module example
%{
#include "example.h"
%}
%typemap(in) std::vector<Bar>* b (std::vector<Bar> temp) {
PyObject* input = $input;
if (!PyList_Check(input)) {
SWIG_exception(SWIG_TypeError, "Input must be a list");
}
for (int i = 0; i < PyList_Size(input); ++i) {
PyObject* obj = PyList_GetItem(input, i);
Bar* bar;
if (SWIG_ConvertPtr(obj, (void**)&bar, $descriptor(Bar), 1) == -1) {
SWIG_exception(SWIG_TypeError, "Input list element was not a Bar");
}
temp.push_back(*bar);
}
$1 = &temp;
}
然而,当我查看生成的代码时,我看到了可能出现问题的地方:
SWIGINTERN PyObject *_wrap_new_Foo(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
std::vector< Bar > *arg1 = (std::vector< Bar > *) 0 ;
std::vector< Bar > temp1 ;
PyObject * obj0 = 0 ;
Foo *result = 0 ;
if (!PyArg_ParseTuple(args,(char *)"O:new_Foo",&obj0)) SWIG_fail;
{
PyObject* input = obj0;
if (!PyList_Check(input)) {
SWIG_exception(SWIG_TypeError, "Input must be a list");
}
for (int i = 0; i < PyList_Size(input); ++i) {
PyObject* obj = PyList_GetItem(input, i);
Bar* bar;
if (SWIG_ConvertPtr(obj, (void**)&bar, SWIGTYPE_Bar, 1) == -1) {
SWIG_exception(SWIG_TypeError, "Input list element was not a Bar");
}
temp1.push_back(*bar);
}
arg1 = &temp1;
}
result = (Foo *)new Foo(arg1);
resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_Foo, SWIG_POINTER_NEW | 0 );
return resultobj;
fail:
return NULL;
}
也就是说,Foo* 类型的结果是使用指向局部变量 (arg1 = &temp1
) 的指针创建的。这看起来是错误的。无论如何我可以正确地做到这一点吗?我是 SWIG 的新手,因此指向解决此问题的文档的指针也很有用。
我是否可以在不更改 C++ 接口(interface)的情况下至少模拟构造函数参数的拷贝?也就是说,创建 python Foo(my_list_of_bars)
将表现得好像要包装的 c++ 代码是 Foo(std::vector<Bar> b)
.我认为我可以在类型映射中做的一件事是使用临时指针,从 python 列表中复制值,然后将其传递给 Foo。所以第一行会变成:
%typemap(in) std::vector<Bar>* b (std::vector<Bar> *temp) {
temp = new std::vector<Bar>;
但是我怎样才能清理生成的代码中的临时文件?
最佳答案
如您所见,尝试传递 Python 列表只会创建一个临时的 std::vector 来调用 Foo 构造函数。要创建一个可以管理其生命周期的永久类,请将 std::vector 类公开给 Python,构建一个,然后传递它:
例子:
%module x
%{
#include <vector>
%}
%inline %{
struct Bar {
int data;
};
%}
%include <std_vector.i>
%template(BarVec) std::vector<Bar>;
%inline %{
class Foo {
std::vector<Bar>* b_;
public:
// does not take ownership.
Foo(std::vector<Bar>* b) { b_ = b; }
std::vector<Bar>* get() { return b_; } # Added to inspect that it worked.
};
%}
演示:
>>> import x
>>> v = x.BarVec()
>>> for i in range(10):
... b = x.Bar()
... b.data = i
... v.push_back(b)
...
>>> f = x.Foo(v)
>>> v2 = f.get()
>>> v[5].data
5
>>> v2[5].data
5
>>> v[5].data = 7 # Change original vector data passed in.
>>> v2[5].data # vector from Foo also changes.
7
>>> del v # delete the original vector
>>> v2 # proxy is still there
<x.BarVec; proxy of <Swig Object of type 'std::vector< Bar > *' at 0x00000000027CA4C0> >
>>> v2[0] # <CRASH>
关于python - 痛饮 python : inject pointer on construction,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22364395/
今天我尝试使用“cmake + swig”的组合来为我的代码生成绑定(bind)。基本上它有效: set(SWIG_EXECUTABLE "/usr/bin/swig") find_package(S
我正在尝试从使用 SWIG for Python 包装的 C 函数中输出一组值。我尝试做的方式是使用以下类型映射。 伪代码: int oldmain() { float *output = {0,1}
假设 C++ 类结构如下: namespace MainNS { namespace A { class Class { //.
我正在尝试了解 SWIG 的工作原理。假设我有这个简单的 Foo-Bar 类: #include class Bar { public: Bar(); ~Bar(); int bar_
我正在尝试使用 Swig 从 CXX 模块构建 Perl 模块。有多个与此相关的指南: 通用 Swig tutorial带有 Perl 部分 Swig and C++指导 Swig and Perl5
我正在使用 Swig 将 C/C++ 包装到 Java 中。 我有这个结构: struct score { void* goals; uint32_t goals_number; }
我想使用 swig(它是我的模板引擎)插入 JavaScript,以便只有在选择“其他”选项时才会显示以下内容。 Select Switch Manufacturer Cisco N
我对 SWIG ( C + python ) 有一个奇怪的问题 在 C 中,我有一个返回指向结构 elements_t 的指针的函数。我在 python 中调用函数,得到结果(指针)但我无法访问结构的
我正在尝试为 python 创建一个提供 mysql 连接的 swig 包。但是当我尝试在 python 中导入包时,出现以下错误: -> _mod = imp.load_module('_IMysq
给定这组文件: foo.h: #pragma once #include template class Foo { public: T0 m[3]; Foo(const T0
我是 SWIG 的新手。我创建了一个 python 模块来使用 C++ 类。 我的cpp头代码是 渐变复杂.h : class GradedComplex { public: typedef st
我在 C++ 文件中有类似的东西,它们组成了我的 SWIG 模块: class CObject { public: void do() { // som
我正在使用 SWIG 为我的一个 C 库生成 Java 绑定(bind)。但是我在处理 C 指针时遇到了麻烦。下面是一些代码来演示我的问题: calc.h 文件: extern int sum(int
我是 SWIG 的新手,我使用的相机使用 SWIG 在 Python 中封装 C++。这台相机很特别,因为我无法直接获取原始图像。然后我找到/添加一个可以制作快照的 C++ 函数,它是: int Pi
我正在研究如何使用 swig 为我的 python 代码进行 C 扩展。我使用从网站获得的代码作为示例。这是我的代码: example.c #include double My_variable
我正在尝试使用 SWIG 在 Go 中包装一个 C++ 库,但是自从我升级到 Go 1.4.2 后,我在尝试使用该包时遇到了构建错误。 包可以在这里找到: https://bitbucket.org/
我使用 Swig 从 C/C++ 代码生成 Java 代码。 我得到了很多非人类可读的类,有点像“SWIG_p_f_p_......”,等等。 但是,我需要我最终生成的类遵守一些命名规则。 例如: S
我正在尝试使用 SWIG 在 Go 中包装这个库 ( https://github.com/lemire/EWAHBoolArray ),但是自从我升级到 1.4 后我遇到了很多问题 我已成功使用 G
自从我使用 Swig 以来已经有一段时间了,所以这可能是一些愚蠢的错误。 我使用 swig 为一组函数创建了接口(interface),但有些地方不对劲。例如,当我尝试调用 c 中需要 (int *)
我是一名优秀的程序员,十分优秀!