Notes:
I've prepared a full (and dummy) example, to illustrate the behavior.
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()
Output:
[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)