/*** type define class template for extern "C" ***/
typedef Mpoly<double> MpolyDouble;
// Declare functions as extern "C" for ctypes
//
// >> compiler statement (mac/linux): g++ -shared -o libPoly.so -fPIC libPoly.cpp
// >> compiler statement (windows): g++ -shared -o libPoly.dll libPoly.cpp
//
extern "C" {
/*** libPoly Constructor/Destructor Routines ***/
MpolyDouble* Poly_new(int size, int dim) { return new(nothrow) MpolyDouble(size,dim); }
void Poly_del(MpolyDouble* foo) { delete foo; }
/*** libPoly Miscellaneous Routines ***/
void PolyPrint(MpolyDouble* foo) {
// print out address of object pointer
std::cout << "address of foo: " << foo << std::endl;
// call MpolyDouble.print() method
foo->print();
}
}
#*** import python libraries ***#
from ctypes import *
from numpy.ctypeslib import ndpointer
import numpy as np
import weakref
#**************************************#
#*** load the libPoly shared object ***#
#**************************************#
lib = CDLL('./libPoly.so') #! for Mac/Linux
#lib = CDLL('./libPoly.dll') #! for Windows
#********************************************************#
#*** set the argument types for each member attribute ***#
#********************************************************#
## Poly_new
lib.Poly_new.argtypes = [c_int, c_int]
lib.Poly_new.restype = c_void_p
## Poly_del
lib.Poly_del.argtypes = [c_void_p] #<---edit
lib.Poly_del.restype = None
## PolyPrint
lib.PolyPrint.argtypes = [c_void_p] #<---edit
lib.PolyPrint.restype = None
#********************************************************#
#*** define a python class Poly ***#
#********************************************************#
class Poly(object):
# GHV Instantiation Routine:
def __init__(self,size=1,dim=2):
# ensure that the input args are of correct type
size = int(size)
dim = int(dim)
# call the C/C++ function
self.obj = lib.Poly_new(size,dim)
def __del__(self):
lib.Poly_del(self.obj)
self._obj = None
# GHV Print Routine:
def Print(self):
print 'address of self.obj',hex(id(self.obj))
# call the C/C++ function
lib.PolyPrint(self.obj)
$ python
来自PolyWrapper import * 的
P = Poly()
P.Print()
self.obj的地址0x10038fc08
foo的地址:0x1804810
分段错误:11
流程:python2.7 [3359]
路径:/ Users / USER / * / python2.7
标识符:python2.7
代码类型:X86-64(原生) 家长程序:bash [3341] 负责人:终端[235]
日期/时间:2016-02-16 12:48:22.220 -0500 操作系统版本:Mac OS X 10.11.3(15D21)
异常类型:EXC_BAD_ACCESS(SIGSEGV)
异常代码:KERN_INVALID_ADDRESS位于0x0000000001804810
为什么这可以在我的Windows平台上运行,而不是在其他任何地方?
我在任一平台上都没有出现任何编译器错误。另外,我使用typedef来通过函数模板并没有给我带来其他类似项目的问题。
请注意,.cpp文件中打印的foo&#39;地址与在控制台中引发警报的地址相同&#39;例外代码&#39;。 python在创建新对象时是否收到正确的地址?怎么说,怎么可能?
报告了类似的问题here,但我不相信这是问题所在,因为我已明确设置restype
,argtype
和{ {1}}。
argtypes
- g++ --version
(OS X)和Apple LLVM version 7.0.2 (clang-700.1.81)
(Windows CygWIN)。如果您认为编译器可能是问题,请注意我使用相同的编译器生成lib.so和lib.dll。 Spyder的执行(Python(x,y))有效;从CygWIN shell执行lib.so给出了SIG11。
答案 0 :(得分:2)
这是我的最终解决方案。我没有对c ++方面做过任何重大改变 - 只有Python ctypes绑定。我还添加了一些逻辑来处理动态库(共享对象)的导入,这不是一般的。它适用于我的两个工作站和其他一些我必须协作的其他工作站,除了32位版本的Python2.7。
__del__
例程可以轻松链接到c ++对象的析构函数例程,这在传递时是必不可少的来回作为指针。lib
称为全局的错误,直到唤起__del__
才给我带来问题;但是,在调用lib.Poly_del(self.obj)
时,lib
不再被定义。#*************************************#
#*** import python libraries ***#
#*************************************#
from ctypes import *
from numpy.ctypeslib import ndpointer
import numpy as np
import weakref
import platform
#**************************************#
#*** load the libPoly shared object ***#
#**************************************#
print.system()
if (platform.system() == "Windows" or platform.system() == "CYGWIN-6.1"):
lib = CDLL('./libPoly.dll')
else:
lib = CDLL('./libPoly.so')
#********************************************************#
#*** set the argument types for each member attribute ***#
#********************************************************#
## Poly_new
lib.Poly_new.argtypes = [c_int, c_int]
lib.Poly_new.restype = c_void_p
## Poly_del
lib.Poly_del.argtypes = [c_void_p]
lib.Poly_del.restype = None
## PolyPrint
lib.PolyPrint.argtypes = [c_void_p]
lib.PolyPrint.restype = None
#********************************************************#
#*** define a python class Poly ***#
#********************************************************#
class Poly(object):
_obj = None
_local = lib
# Poly Instantiation Routine:
def __init__(self,size=1,dim=1):
# ensure that the input args are of correct type
size = int(size)
dim = int(dim)
# call the C/C++ function
self._obj = c_void_p(self._lib.Poly_new(size,dim))
# Poly Destructor Routine:
def __del__(self):
if (self._obj is not None):
self._lib.Poly_del(self._obj)
del self._obj
# Poly Print Routine:
def Print(self):
# call the C/C++ function
self._lib.PolyPrint(self._obj)