I'm trying to access a C++ class from python using ctypes. Wrapper functions to access the C++ functionality are exposed in a DLL.
I have a C++ data class. An instance of the class is made in the first function call from python to C++, and a pointer to this instance is passed back. The second python function call takes the pointer as an arg and prints some of its data.
The problem is that the pointer address is truncated. When printing the pointer just after the class instance is made, it looks like "000001A05127F110". Then when the pointer is printed again within C++ in the second function call, it looks like "000000005127F110".
I'm using python 3.6.8 x64, MSVC x64.
I've tried setting the argtypes
and the restypes
to various ctypes builtin types, but it has not fixed the problem.
Interestingly, this is the second time that I have tried to do this. In the past the same solution that I am using here worked fine under the same (or similar) circumstances.
data_wrapper.h
#include <string>
class DataWrapper
{
public:
DataWrapper()
{
m_temp = std::string("hi");
}
virtual ~DataWrapper()
{
std::cout << "Deleting" << std::endl;
}
std::string m_temp;
};
wrapper.cpp
#include <iostream>
#include <string>
#include "cogitant/data_wrapper.h"
#define DLLEXPORT extern "C" __declspec(dllexport)
DLLEXPORT void checkData(DataWrapper * d)
{
std::cout << d << std::endl;
//std::cout << d->m_temp << std::endl;
}
DLLEXPORT DataWrapper * makeData()
{
DataWrapper * d = new DataWrapper();
std::cout << d << std::endl;
return d;
}
main.py
import ctypes
CPP_LIB_DLL_LOC = "<my path>/data_wrapper.dll"
LIB = ctypes.cdll.LoadLibrary(CPP_LIB_DLL_LOC)
def main():
print("Starting. . .")
#make new data class
make_func = LIB.makeData
make_func.argtypes = []
make_func.restypes = ctypes.c_void_p
dataclass = make_func()
print(dataclass)
print(type(dataclass ))
#check the dataclass pointer is valid
check_func = LIB.checkData
check_func.restypes = None
check_func.argtypes = [ctypes.c_void_p]
check_func(dataclass)
print("Finished.")
if __name__ == "__main__":
main()
Here is the python output:
Starting. . .
000001ED0E612320
241247008
<class 'int'>
000000000E612320
Finished.
I'd expect these two addresses to be the same. If I uncomment the line in wrapper.cpp
then I see the following error:
File "<my path>/python/main.py", line 21, in main
check_func(dataclass)
OSError: exception: access violation reading 0x000000000E612320