This is a very old post, and probably the OP already found a solution to his problem, but since no one has yet provided a valid example, I will give it a try and maybe help someone like me with the same problem in hand.
Since the OP did not specify, I will restrict my answer to Windows, although a Linux solution would be straightforward. I will try to provide a minimal working example that reproduces the code in question.
Step 1) Start with the C++ code (a single file)
class Test{
private:
int n;
public:
Test(int k){
n=k;
}
void setInt(int k){
n = k;
}
int getInt(){
return n;
}
};
extern "C"
{
// include below each method you want to make visible outside
__declspec(dllexport) Test* init(int k) {return new Test(k);}
__declspec(dllexport) void setInt(Test *self, int k) {self->setInt(k);}
__declspec(dllexport) int getInt(Test *self) {return self->getInt();}
// Note: the '__declspec(dllexport)' is only necessary in Windows
}
Step 2) Compile the DLL shared library. E.g. from your working directory:
g++ -shared mytest.cpp -o libtest.dll
Step 3) Create the Python file with the wrapper:
# mytest.py
import ctypes
import platform
# From Python 3.8 onwards, there is a reported bug in CDLL.__init__()
mode = dict(winmode=0) if platform.python_version() >= '3.8' else dict()
lib = ctypes.CDLL('./libtest.dll', **mode)
class Test(object):
def __init__(self, val: int):
# Declare input and output types for each method you intend to use
lib.init.argtypes = [ctypes.c_int]
lib.init.restype = ctypes.c_void_p
lib.setInt.argtypes = [ctypes.c_void_p, ctypes.c_int]
lib.setInt.restype = ctypes.c_void_p
lib.getInt.argtypes = [ctypes.c_void_p]
lib.getInt.restype = ctypes.c_int
self.obj = lib.init(val)
def setInt(self, n):
lib.setInt(self.obj, n)
def getInt(self):
return lib.getInt(self.obj)
T1 = Test(12)
print(T1.getInt())
T1.setInt(32)
print(T1.getInt())
Step 4) Run the code
Below are my results when I run the script with 4 different Python versions:
PS D:\Desktop\mytest> py -3.7 .\mytest.py
12
32
PS D:\Desktop\mytest> py -3.8 .\mytest.py
12
32
PS D:\Desktop\mytest> py -3.9 .\mytest.py
12
32
PS D:\Desktop\mytest> py -3.10 .\mytest.py
Traceback (most recent call last):
File "D:\Desktop\mytest\mytest.py", line 7, in <module>
lib = ctypes.CDLL('./libtest.dll', **mode)
File "D:\Python\3102\lib\ctypes\__init__.py", line 374, in __init__
self._handle = _dlopen(self._name, mode)
FileNotFoundError: Could not find module 'D:\Desktop\mytest\libtest.dll' (or one of its dependencies). Try using the full path with constructor syntax.
In the last case, I have tried with the full path and still same error.
I'm running on Windows 10 64bit and compiling with g++ 8.1.0 from MinGW64
Comments:
- My answer is based in the solutions provided here, here, and here
- A common problem arises when the Python and compiler (g++) architectures does not match (i.e. 32 or 64 bit)