我正在尝试使用ctypes从python访问C ++类。 DLL中公开了用于访问C ++功能的包装器功能。
我有一个C ++数据类。在从python到C ++的第一个函数调用中创建该类的实例,并将指向该实例的指针传回。第二个python函数调用将指针作为arg并打印其一些数据。
问题是指针地址被截断了。在创建类实例之后立即打印指针时,它看起来像“ 000001A05127F110”。然后,在第二个函数调用中再次在C ++中打印指针时,它看起来像是“ 000000005127F110”。
我正在使用python 3.6.8 x64,MSVC x64。
我尝试将argtypes
和restypes
设置为各种内置的ctypes类型,但是并不能解决问题。
有趣的是,这是我第二次尝试这样做。过去,在相同(或相似)情况下,我在此处使用的相同解决方案效果很好。
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()
这是python输出:
Starting. . .
000001ED0E612320
241247008
<class 'int'>
000000000E612320
Finished.
我希望这两个地址相同。如果取消注释wrapper.cpp
中的行,则会看到以下错误:
File "<my path>/python/main.py", line 21, in main
check_func(dataclass)
OSError: exception: access violation reading 0x000000000E612320
答案 0 :(得分:0)
它是6.14
而不是returns 6.15
。
这解决了我遇到的问题。
可以确认:
restype
确实会导致错误。