C/Python绑定:指针地址修改 来源
C++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: " <
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默认为Cint
,正如您所发现的,它截断了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);