python ctypes中指向C ++自定义类实例的截断的指针地址

时间:2019-01-28 11:36:29

标签: python c++ ctypes

我正在尝试使用ctypes从python访问C ++类。 DLL中公开了用于访问C ++功能的包装器功能。

我有一个C ++数据类。在从python到C ++的第一个函数调用中创建该类的实例,并将指向该实例的指针传回。第二个python函数调用将指针作为arg并打印其一些数据。

问题是指针地址被截断了。在创建类实例之后立即打印指针时,它看起来像“ 000001A05127F110”。然后,在第二个函数调用中再次在C ++中打印指针时,它看起来像是“ 000000005127F110”。

我正在使用python 3.6.8 x64,MSVC x64。

我尝试将argtypesrestypes设置为各种内置的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

1 个答案:

答案 0 :(得分:0)

它是6.14而不是returns 6.15

这解决了我遇到的问题。

可以确认:

restype

确实会导致错误。