首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >SWIG:避免C++到Python混叠

SWIG:避免C++到Python混叠
EN

Stack Overflow用户
提问于 2020-08-05 07:57:17
回答 1查看 117关注 0票数 0

我正在C++中构建一个库,该库使用4.0.1与Python3进行接口。经过一段时间的发展,我注意到一个问题(我认为这是所谓的)别名。我准备了一个最小的例子,这也发生了。

考虑具有单个(私有)属性dummy的类attr,该属性在0处初始化。现在,我有了一个非常小的python脚本:

代码语言:javascript
代码运行次数:0
运行
复制
import dummy_wrap
d1 = dummy_wrap.dummy()
d2 = d1
d1.set_attr(12)
print(d2.get_attr()) # this prints '12', not '0'

我希望我所说的混叠是这里真正发生的事情:对象d2从未被修改过,但是它接受给d1的值,就好像赋值d2=d1实际上是指针赋值一样。我想要发生的事情(以及我希望发生的事情)是赋值操作符a=bb的硬拷贝传递给a。换句话说,对a的修改不应影响b,反之亦然,只要这符合实现细节(如我的库和最小示例中的情况)。

最后,这是我在编译时得到的消息:

代码语言:javascript
代码运行次数:0
运行
复制
g++ -fPIC -c dummy.cpp
g++ -fPIC -shared -o libdummy_lib.so dummy.o
swig -Wall -c++ -python -py3 -o dummy_wrap.cxx dummy_wrap.i
dummy.hpp:10: Warning 362: operator= ignored
dummy.hpp:11: Warning 362: operator= ignored
dummy.hpp:7: Warning 509: Overloaded method dummy::dummy(dummy &&) effectively ignored,
dummy.hpp:6: Warning 509: as it is shadowed by dummy::dummy(dummy const &).
g++ -fPIC -c dummy_wrap.cxx -I /usr/include/python3.8
g++ -fPIC -shared -o _dummy_wrap.so dummy_wrap.o -L . -ldummy_lib -lpython3.8

问题:

我想了解这里发生了什么,以及为什么:dummy& operator=(const dummy&)

  • Is和dummy(dummy&&)是否会影响到SWIG包装dummy(const dummy&)dummy(const dummy&)的方式?可以合理地预期我希望拥有的默认行为,即:这是类在使用SWIG与python接口后的预期行为吗?

  • 如何修复这个问题:我应该做哪些更改以使操作符=生成一个硬拷贝?

F 228>

提前谢谢。

为了复制这一点,类头dummy.hpp是:

代码语言:javascript
代码运行次数:0
运行
复制
#pragma once

class dummy {
    public:
        dummy() = default;
        dummy(const dummy&) = default;
        dummy(dummy&&) = default;
        ~dummy() = default;
        dummy& operator=(const dummy&) = default;
        dummy& operator=(dummy&&) = default;
        void set_attr(int v);
        int get_attr() const;
    private:
        int attr = 0;
};

类实现dummy.cpp是简单的

代码语言:javascript
代码运行次数:0
运行
复制
#include "dummy.hpp"
void dummy::set_attr(int v) { attr = v; }
int dummy::get_attr() const { return attr; }

接口文件dummy_wrap.i是:

代码语言:javascript
代码运行次数:0
运行
复制
%module dummy_wrap
%{
#include "dummy.hpp"
%}
%include "dummy.hpp"

我用来编译和链接所有东西的Makefile

代码语言:javascript
代码运行次数:0
运行
复制
all: libdummy_lib.so _dummy_wrap.so
_dummy_wrap.so: dummy_wrap.o
    g++ -fPIC -shared -o _dummy_wrap.so dummy_wrap.o -L . -ldummy_lib -lpython3.8
dummy_wrap.o: dummy_wrap.cxx
    g++ -std=c++17 -fPIC -c dummy_wrap.cxx -I /usr/include/python3.8
dummy_wrap.cxx: dummy_wrap.i
    swig -Wall -c++ -python -py3 -o dummy_wrap.cxx dummy_wrap.i
libdummy_lib.so: dummy.o
    g++ -fPIC -shared -o libdummy_lib.so dummy.o
dummy.o: dummy.cpp dummy.hpp
    g++ -std=c++17 -fPIC -c dummy.cpp
clean:
    rm -f libdummy_lib.so dummy.o
    rm -f _dummy_wrap.so dummy_wrap.o dummy_wrap.cxx dummy_wrap.py

在linux中,请记住使用以下方法更新LD_LIBRARY_PATH

代码语言:javascript
代码运行次数:0
运行
复制
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-08-06 06:26:56

因此,多亏了最初文章中的一些注释,一个可能的解决方案是添加一个clone()方法。可以通过简单地扩展C++头来实现这一点。但是,由于这在某些人看来可能很奇怪,因为在许多情况下,clone()方法在C++中根本没有必要,所以我们可以使用SWIG扩展python类。简单地以示例中的dummy_wrap.i为例,并在文件末尾添加以下代码

代码语言:javascript
代码运行次数:0
运行
复制
%extend dummy {
    dummy clone() const {
        return *$self;
    }
}

不幸的是,这并没有在这里结束,因为我们的python代码必须修改:

代码语言:javascript
代码运行次数:0
运行
复制
import dummy_wrap
d1 = dummy_wrap.dummy()
d2 = d1.clone()
d1.set_attr(12)
print(d2.get_attr()) # now this prints '0'
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63260754

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档