class A{
A();
void a();
virtual void v();
}
将此文件保存到liba.so
class B : A {
B();
void b();
void v();
}
extern "C" {
A* newB() {
return new B();
}
void calla(A*b) {
b->a();
}
void callv(A*b) {
b->v();
}
}
将此文件保存到libb.so
在python中:
from ctypes import cdll
lib = cdll.LoadLibrary('./libb.so')
class B(object):
def __init__(self):
self.obj = lib.newb()
def a(self):
lib.calla(self.obj)
def v(self):
lib.callv(self.obj)
b = B()
b.a() # call base class function, that's ok
b.v() # call derive class virtual function , segment fault!
这是否意味着python无法使用包含继承逻辑的dll?
似乎python无法调用c ++类,因为其函数入口更改为bc继承逻辑,任何人都可以谈论此事吗?
谢谢
答案 0 :(得分:0)
注释:
我准备了一个完整的(并且是虚拟的)示例来说明这种行为。
a.h :
#pragma once
#define COUT() std::cout << __FILE__ << ":" << __LINE__ << "(" << __FUNCTION__ << ")\n"
#if defined(_WIN32)
# define DLL_EXPORT __declspec(dllexport)
#else
# define DLL_EXPORT
#endif
class DLL_EXPORT A {
public:
A();
virtual ~A();
void a();
virtual void v();
};
a.cpp :
#include "a.h"
#include <iostream>
A::A() {
COUT();
}
A::~A() {
COUT();
}
void A::a() {
COUT();
}
void A::v() {
COUT();
}
b.h :
#pragma once
#include "a.h"
class B : public A {
public:
B();
void b();
void v();
};
extern "C" {
DLL_EXPORT A *newB() {
return new B();
}
DLL_EXPORT void calla(A *b) {
b->a();
}
DLL_EXPORT void callv(A *b) {
b->v();
}
DLL_EXPORT void delB(A *b)
{
delete b;
}
}
b.cpp :
#include "b.h"
#include <iostream>
B::B() :
A() {
COUT();
}
void B::b() {
COUT();
}
void B::v() {
COUT();
}
code.py :
#!/usr/bin/env python3
import sys
import ctypes
LIB_NAME = "./libb.so"
class B(object):
def __init__(self, lib_name=LIB_NAME):
self.lib = ctypes.cdll.LoadLibrary(lib_name)
self.lib.newB.restype = ctypes.c_void_p
self.obj = self.lib.newB()
def a(self):
self.lib.calla.argtypes = [ctypes.c_void_p]
self.lib.calla(self.obj)
def v(self):
self.lib.callv.argtypes = [ctypes.c_void_p]
self.lib.callv(self.obj)
def __del__(self):
self.lib.delB.argtypes = [ctypes.c_void_p]
self.lib.delB(self.obj)
self.obj = None
self.lib = None
def main():
b = B()
b.a()
b.v()
if __name__ == "__main__":
print("Python {:s} on {:s}\n".format(sys.version, sys.platform))
main()
输出:
[cfati@cfati-5510-0:/cygdrive/e/Work/Dev/StackOverflow/q054646019]> ls a.cpp a.h b.cpp b.h code.py [cfati@cfati-5510-0:/cygdrive/e/Work/Dev/StackOverflow/q054646019]> g++ -shared -fPIC -o liba.so a.cpp [cfati@cfati-5510-0:/cygdrive/e/Work/Dev/StackOverflow/q054646019]> g++ -shared -fPIC -o libb.so b.cpp ./liba.so [cfati@cfati-5510-0:/cygdrive/e/Work/Dev/StackOverflow/q054646019]> ls a.cpp a.h b.cpp b.h code.py liba.so libb.so [cfati@cfati-5510-0:/cygdrive/e/Work/Dev/StackOverflow/q054646019]> python3 code.py Python 3.6.4 (default, Jan 7 2018, 15:53:53) [GCC 6.4.0] on cygwin a.cpp:6(A) b.cpp:7(B) a.cpp:14(a) b.cpp:15(v) a.cpp:10(~A)