swig python 派生类和基类位于不同模块中

huangapple go评论70阅读模式
英文:

swig python derived and base in different modules

问题

I am trying to reproduce a python example from the swig 4.0 documentation Modules Basics. I got properly generated _base_module.so and _derived_module.so. However when I try to use the derived module from my test program:

#!/usr/bin/env python3

import sys
import derived_module
...

I got an import error: ImportError: /homes/../_derived_module.so: undefined symbol: _ZTI4Base

The reason for the error is quite understandable but it is not clear how to avoid it. Below are my files.

base.h:

#ifndef _BASE_H_INCLUDED_
#define _BASE_H_INCLUDED_

class base {
public:
    virtual int foo();
};

#endif // _BASE_H_INCLUDED_

base.cpp:

#include "base.h"

int base::foo() { return 10; }

base_module.i:

%module base_module

%{
#include "base.h"
%}
%include base.h

derived_module.i:

%module derived_module

%{
#include "base.h"
%}

%import(module="base_module") "base.h"

%inline %{
class derived : public base {
public:
    int foo() override { return 20; }
};
%}

test.py:

#!/usr/bin/env python3

import sys
import derived_module

if __name__ == "__main__":
    derived = derived_module.derived()
    res = derived.foo()
    print("res={}".format(res))
    sys.exit()

Makefile:

SWIG = swig4
CCX = g++

LD = g++

all: derived_module.py

derived_module.py: base.h base.cpp base_module.i derived_module.i
        ${SWIG} -python -py3 -c++ -cppext cpp base_module.i
        ${SWIG} -python -py3 -c++ -cppext cpp derived_module.i
        ${CCX} -O2 -fPIC -c base.cpp
        ${CCX} -O2 -fPIC -c base_module_wrap.cpp -I/usr/include/python3.8
        ${CCX} -O2 -fPIC -c derived_module_wrap.cpp -I/usr/include/python3.8
        ${LD} -shared base.o base_module_wrap.o -o _base_module.so
        ${LD} -shared derived_module_wrap.o -o _derived_module.so

run: derived_module.py
        python3 ./test.py

clean:
        rm -rf *~ derived_module.py base_module.py *_wrap.* *.o *.so __pycache__
英文:

I am trying to reproduce a python example from the swig 4.0 documentation Modules Basics. I got properly generated _base_module.so and _derived_module.so . However when I try to use derived module from my test program

#!/usr/bin/env python3

import sys
import derived_module
...

I got an import error:ImportError: /homes/../_derived_module.so: undefined symbol: _ZTI4Base

The reason for the error is quite understandable but it is not clear how to avoid it. Below are my files.

base.h:

#ifndef _BASE_H_INCLUDED_
#define _BASE_H_INCLUDED_

class base {
public:
    virtual int foo();
};

#endif // _BASE_H_INCLUDED_

base.cpp:

#include "base.h"

int base::foo() { return 10; }

base_module.i:

%module base_module

%{
#include "base.h"
%}
%include base.h

derived_module.i:

%module derived_module

%{
#include "base.h"
%}

%import(module="base_module") "base.h"

%inline %{
class derived : public base {
public:
    int foo() override { return 20; }
};
%}

test.py:

#!/usr/bin/env python3

import sys
import derived_module

if __name__ == "__main__":
    derived = derived_module.derived();
    res = derived.foo();
    print("res={}".format(res));
    sys.exit()

Makefile:

SWIG = swig4
CCX = g++

LD = g++

all: derived_module.py

derived_module.py: base.h base.cpp base_module.i derived_module.i
        ${SWIG} -python -py3 -c++ -cppext cpp base_module.i
        ${SWIG} -python -py3 -c++ -cppext cpp derived_module.i
        ${CCX} -O2 -fPIC -c base.cpp
        ${CCX} -O2 -fPIC -c base_module_wrap.cpp -I/usr/include/python3.8
        ${CCX} -O2 -fPIC -c derived_module_wrap.cpp -I/usr/include/python3.8
        ${LD} -shared base.o base_module_wrap.o -o _base_module.so
        ${LD} -shared derived_module_wrap.o -o _derived_module.so

run: derived_module.py
        python3 ./test.py

clean:
        rm -rf *~ derived_module.py base_module.py *_wrap.* *.o *.so __pycache__

答案1

得分: 1

我无法使用您的工具链进行此测试,因为我目前只有MSVC和Windows系统,但您需要将base.o链接到派生模块中:

${LD} -shared base.o derived_module_wrap.o -o _derived_module.so

您可能还希望将base.o制作成共享模块,以避免代码重复。
在使用MSVC时,两种方式都对我起作用。

英文:

I can't test this with your toolchain because I only have MSVC and a Windows system at the moment, but you need to link base.o into the derived module as well:

${LD} -shared base.o derived_module_wrap.o -o _derived_module.so

You may want to make base.o into a shared module as well so there is no duplication of code.

It worked both ways for me using MSVC.

huangapple
  • 本文由 发表于 2023年4月19日 21:40:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/76055244.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定