【问题标题】:SWIG: read/write same variable from python and C++SWIG:从 python 和 C++ 读/写相同的变量
【发布时间】:2020-10-14 14:17:14
【问题描述】:

我不确定我在这里是否走对了路。

(见下方编辑)

我有一个名为 myapp 的 C++ 库,它编译成 libmyapp.so。该库包含一个名为swigtest.h 的文件。 我想做的事情是用 SWIG 包装这个文件,为 python 创建一个接口,并使用这个接口从myapp 更改或读取特定值。
假设myapp 是一个控制台应用程序,它具有一些全局变量,例如static int myGlobalVar = 5


myapp我有一个读写全局变量的函数:

int ReadGlobalVar() { return myGlobalVar; }
void SetGlobalVar(int value) { myGlobalVar = value; }

这是我编译模块的步骤:

swig -c++ -python swigtest.i
g++ -fpic -c swigtest.cpp swigtest_wrap.cxx -L/pathToMyApp -lmyapp -I/usr/include/python3.6
g++ -Wall -Wextra -shared swigtest.o swigtest_wrap.o -o _swigtest.so -L/pathToMyApp -lmyapp

我打开并加载python模块如下:

LD_LIBRARY_PATH=/pathToMyApp python3
import swigtest
...

我知道的问题是,python 和我的应用程序仍然彼此分离。如果我使用 python 模块修改变量,它不会影响 c++ 应用程序,反之亦然。

甚至可以将这两者链接在一起,还是 SWIG 仅用于在 python 中重用 C++ 代码?
我认为这里最大的问题是我对在 C++ 下如何链接和创建库只有一点了解。
我找到了一些关于在 Python 中使用 SWIG 的教程,例如:
http://books.gigatux.nl/mirror/pythonprogramming/0596000855_python2-CHP-19-SECT-8.html
https://www.geeksforgeeks.org/wrapping-cc-python-using-swig-set-1/

====================

编辑:

我为此场景创建了另一个示例应用程序:

1) 文件:

main.cpp

#include 
#include 
#include 

#include “Swigtest.h”


使用命名空间标准;
主函数()
{
    最猛烈的;最猛烈的;

    为了(;;)
    {
        睡眠(1);
        cout 

Swigtest.h

#ifndef SWIGTEST_H
#define SWIGTEST_H

静态 int myGlobalVar = 5;

类 Swigtest
{
民众:
    Swigtest();

    无效 SetGlobalVar(int var){ myGlobalVar = var; }
    int ReadGlobalVar() { return myGlobalVar; }
};

#endif // SWIGTEST_H

Swigtest.cpp

#include "Swigtest.h"

Swigtest::Swigtest()
{
}

Swigtest.i

%module swigtest

%{
#include "Swigtest.h"
%}

%include "Swigtest.h"

2) 编译应用程序

g++ -fpic -c Swigtest.cpp
g++ -fpic -c main.cpp
g++ Swigtest.o main.o -o libmyapp.so

3) 编译python模块

swig -c++ -python Swigtest.i
g++ -fpic -c Swigtest.cpp Swigtest_wrap.cxx -L. -lmyapp -I/usr/include/python3.6
g++ -Wall -Wextra -shared Swigtest.o Swigtest_wrap.o -o _swigtest.so -L. -lmyapp

现在我在myapp.so 中有我的应用程序,在_swigtest.so 中有python 扩展

4) 执行测试

执行应用程序

我通过从 shell 执行应用程序来启动它:

./libmyapp.so

输出:

Global Variable value:5
Global Variable value:5
Global Variable value:5
Global Variable value:5
Global Variable value:5
Global Variable value:5
Global Variable value:5
Global Variable value:5
Global Variable value:5
Global Variable value:5
Global Variable value:5
Global Variable value:5
Global Variable value:5
Global Variable value:5
Global Variable value:5

测试python模块

在另一个终端中,我打开 python(在放置 libmyapp.so 的同一路径)并导入模块

LD_LIBRARY_PATH=. python3

输出:

Python 3.6.9 (default, Nov  7 2019, 10:44:02) 
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import swigtest
>>> a=swigtest.Swigtest()
>>> a.ReadGlobalVar()
5
>>> a.SetGlobalVar(3)
>>> a.ReadGlobalVar()
3
>>> a.ReadGlobalVar()
3
>>> 

与此同时,我从终端启动的 c++ 应用程序正在愉快地输出它的值 5。

我想要什么?

我希望值的变化也会影响 c++ 应用程序。上面我将python模块中的值从5改为3,但c++应用程序并没有受到影响。

这可以通过 SWIG 实现吗?还是我在这里做错了什么。

【问题讨论】:

  • ReadGlobalVar 返回值时如何为空?
  • @armagedescu 我的错是意外混合了 ReadGlobalVar 和 SetGlobalVar。更正了
  • 考虑在你的函数中添加一些输出,看看函数是否真的被调用了。
  • 添加更详细的“逐步”说明您所做的、您期望的以及您实际得到的。需要一些更明确的场景。
  • @armagedescu 我创建了一个新的示例应用程序并编辑了描述。谢谢

标签: python c++ linker g++ swig


【解决方案1】:

在 Python 中它会发生变化,因为它在 C++ 中会发生变化。但它改变了 Python 进程中的 C++ 值。每个进程都在完全分离的上下文中运行。因此,当您单独启动 C++ 进程时,它会在完全不同的上下文中运行,拥有自己的一组变量、内存、注册表。无论你在一个进程中做什么都不会影响其他进程。无论您启动多少进程,都不会影响另一个进程的内容。为了将数据从一个进程发送到另一个进程,您需要一种通过进程间通信 (IPC) 进行通信的方法。您通过文件、套接字、管道、RPC、消息发送数据。

【讨论】:

  • 这是有道理的。我希望通过 SWIG,我可以连接这两个应用程序,而不仅仅是包装 C++ 代码以在其他语言中使用它。
  • 一种可能是将 python 嵌入到 c++ 应用程序中并从那里导入 python 模块。 stackoverflow.com/questions/62919022/…
  • @marsmann007 你做得很好。但这不是答案。尝试启动 Python,修改 C++ 中的值并检查是否看到 Python 中的更改。您必须正确理解一个程序不会以任何方式改变另一个程序。在 Python 中加载 C++ 是在制作一个半 Python 半 C++ 的程序。在 C++ 中加载 Python 时也是如此。它是一个单一的程序,一半是 Python,一半是 C++。唯一改变的是启动程序的部分,C++ 或 Python 部分。其他一切都保持不变。
猜你喜欢
  • 2016-06-22
  • 1970-01-01
  • 2012-07-26
  • 2012-04-26
  • 1970-01-01
  • 2014-04-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多