C/Python绑定:指针地址修改 来源

C/Python绑定:指针地址修改 来源,python,c++,ctypes,language-binding,Python,C++,Ctypes,Language Binding,C++ extern "C" { Service* create_service( int port ) { Settings settings; settings.set_port( port ); auto service = new Service( settings ); std::cout << "create_service returning pointer address: " <

C++

extern "C"
{
    Service* create_service( int port )
    {
        Settings settings;
        settings.set_port( port );

        auto service = new Service( settings );

        std::cout << "create_service returning pointer address: " << service << std::endl;

        return service;
    }

    void release_service( Service* service )
    {
        std::cout << "release_service consuming pointer address: " << service << std::endl;
        delete service;
    }
}
安慰 创建返回指针地址的服务:0x7fc3a0e330e0

init地址:-1595723552

del地址:-1595723552

释放\服务使用指针地址:0xFFFFFFFF0E330E0

分段错误:11

错误 异常类型:EXC\U坏访问(SIGSEGV)

异常代码:0xFFFF914D37A0处的KERN_无效_地址

构建(cmake) 集合(CMAKE_CXX_编译器clang++)

设置(CMAKE_CXX_标志“-stdlib=libc++-std=c++11-Wall-Wextra-Weffc++-pedantic”)

添加库(帮助程序共享${MANIFEST})

目标链接库(帮助器数据库)

描述
<>将C++类实例作为指针返回。Python收到正确的地址。但是,在以后使用此地址时,它似乎已被修改

看来我没有给ctypes提供足够的上下文

from ctypes import *

library = cdll.LoadLibrary('distribution/library/libhelpers.dylib')

class Service(object):
    def __init__(self, port):
        library.create_service.restype = c_void_p
        self.obj = library.create_service(port)

    def __del__(self):
        library.release_service.argtypes = [c_void_p]
        library.release_service(self.obj);

为什么返回局部变量?它已在堆上分配。假设这是可以接受的?“Python收到正确的地址”-在上面的演示中,您还没有演示过这一点。
Settings
不在堆上。@Mat我已经更新了其他日志记录,显示了在Python环境中的地址状态。对于整数,ctypes默认为C
int
,正如您所发现的,它截断了64位指针。您可以直接使用
CDLL
而不是
CDLL.LoadLibrary
cdll
用于Windows,例如
cdll.msvcrt
。顺便说一句,PythoncTypes的典型标记只是“ctypes”,而不是“PythoncTypes”。您应该将设置
restype
argtypes
移出方法定义。每次初始化/取消分配
服务
对象时,都没有必要为单个库实例重新定义它们。
from ctypes import *

library = cdll.LoadLibrary('distribution/library/libhelpers.dylib')

class Service(object):
    def __init__(self, port):
        library.create_service.restype = c_void_p
        self.obj = library.create_service(port)

    def __del__(self):
        library.release_service.argtypes = [c_void_p]
        library.release_service(self.obj);