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

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

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:

  1. #!/usr/bin/env python3
  2. import sys
  3. import derived_module
  4. ...

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:

  1. #ifndef _BASE_H_INCLUDED_
  2. #define _BASE_H_INCLUDED_
  3. class base {
  4. public:
  5. virtual int foo();
  6. };
  7. #endif // _BASE_H_INCLUDED_

base.cpp:

  1. #include "base.h"
  2. int base::foo() { return 10; }

base_module.i:

  1. %module base_module
  2. %{
  3. #include "base.h"
  4. %}
  5. %include base.h

derived_module.i:

  1. %module derived_module
  2. %{
  3. #include "base.h"
  4. %}
  5. %import(module="base_module") "base.h"
  6. %inline %{
  7. class derived : public base {
  8. public:
  9. int foo() override { return 20; }
  10. };
  11. %}

test.py:

  1. #!/usr/bin/env python3
  2. import sys
  3. import derived_module
  4. if __name__ == "__main__":
  5. derived = derived_module.derived()
  6. res = derived.foo()
  7. print("res={}".format(res))
  8. sys.exit()

Makefile:

  1. SWIG = swig4
  2. CCX = g++
  3. LD = g++
  4. all: derived_module.py
  5. derived_module.py: base.h base.cpp base_module.i derived_module.i
  6. ${SWIG} -python -py3 -c++ -cppext cpp base_module.i
  7. ${SWIG} -python -py3 -c++ -cppext cpp derived_module.i
  8. ${CCX} -O2 -fPIC -c base.cpp
  9. ${CCX} -O2 -fPIC -c base_module_wrap.cpp -I/usr/include/python3.8
  10. ${CCX} -O2 -fPIC -c derived_module_wrap.cpp -I/usr/include/python3.8
  11. ${LD} -shared base.o base_module_wrap.o -o _base_module.so
  12. ${LD} -shared derived_module_wrap.o -o _derived_module.so
  13. run: derived_module.py
  14. python3 ./test.py
  15. clean:
  16. 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

  1. #!/usr/bin/env python3
  2. import sys
  3. import derived_module
  4. ...

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:

  1. #ifndef _BASE_H_INCLUDED_
  2. #define _BASE_H_INCLUDED_
  3. class base {
  4. public:
  5. virtual int foo();
  6. };
  7. #endif // _BASE_H_INCLUDED_

base.cpp:

  1. #include "base.h"
  2. int base::foo() { return 10; }

base_module.i:

  1. %module base_module
  2. %{
  3. #include "base.h"
  4. %}
  5. %include base.h

derived_module.i:

  1. %module derived_module
  2. %{
  3. #include "base.h"
  4. %}
  5. %import(module="base_module") "base.h"
  6. %inline %{
  7. class derived : public base {
  8. public:
  9. int foo() override { return 20; }
  10. };
  11. %}

test.py:

  1. #!/usr/bin/env python3
  2. import sys
  3. import derived_module
  4. if __name__ == "__main__":
  5. derived = derived_module.derived();
  6. res = derived.foo();
  7. print("res={}".format(res));
  8. sys.exit()

Makefile:

  1. SWIG = swig4
  2. CCX = g++
  3. LD = g++
  4. all: derived_module.py
  5. derived_module.py: base.h base.cpp base_module.i derived_module.i
  6. ${SWIG} -python -py3 -c++ -cppext cpp base_module.i
  7. ${SWIG} -python -py3 -c++ -cppext cpp derived_module.i
  8. ${CCX} -O2 -fPIC -c base.cpp
  9. ${CCX} -O2 -fPIC -c base_module_wrap.cpp -I/usr/include/python3.8
  10. ${CCX} -O2 -fPIC -c derived_module_wrap.cpp -I/usr/include/python3.8
  11. ${LD} -shared base.o base_module_wrap.o -o _base_module.so
  12. ${LD} -shared derived_module_wrap.o -o _derived_module.so
  13. run: derived_module.py
  14. python3 ./test.py
  15. clean:
  16. rm -rf *~ derived_module.py base_module.py *_wrap.* *.o *.so __pycache__

答案1

得分: 1

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

  1. ${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:

  1. ${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:

确定