SWIG:read/write 来自 python 和 C++ 的相同变量

SWIG: read/write same variable from python and C++

我不太确定我在这里走的路是否正确。

(见下方编辑)

我有一个名为 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++ 应用程序,反之亦然。

是否有可能 link 将这两者结合在一起,或者 SWIG 仅用于在 python 中重用 C++ 代码?
我认为这里的大问题是我对如何在 C++ 下 link 编辑和创建库了解甚少。
我找到了一些关于将 SWIG 与 Python 一起使用的教程,例如:
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 <stdio.h>
#include <unistd.h>
#include <iostream>

#include "Swigtest.h"


using namespace std;
int main()
{
    Swigtest swigtest;

    for(;;)
    {
        sleep(1);
        cout <<  "Global Variable value:" << swigtest.ReadGlobalVar() << endl;
    }
}

Swigtest.h

#ifndef SWIGTEST_H
#define SWIGTEST_H

static int myGlobalVar = 5;

class Swigtest
{
public:
    Swigtest();

    void    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 可以吗?还是我做错了什么。

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