我创建了一个CPP,并试图从python调用其中的函数。对于其他功能,我已经多次做到了,但是这个,我就是找不到我的错误。
dll_name = "..\\src\\x64\\Debug\\2019-3A-IBD-MLDLL.dll"
dllabspath = os.path.dirname(os.path.abspath(__file__)) + os.path.sep + dll_name
myDll = CDLL(dllabspath)
#fit_reg_RBF_naive
myDll.fit_reg_RBF_naive.argtypes = [ct.c_void_p, ct.c_double, ct.c_void_p, ct.c_int, ct.c_int]
myDll.fit_reg_RBF_naive.restypes = ct.c_void_p
#predict_reg_RBF_naive
myDll.predict_reg_RBF_naive.argtypes = [ct.c_void_p, ct.c_void_p, ct.c_void_p, ct.c_int, ct.c_double, ct.c_int]
myDll.predict_reg_RBF_naive.restypes = ct.c_double
def fit_reg_RBF_naive(pyXTrain, pyGamma, pyYTrain, pySampleCount, pyInputCountPerSample):
XTrain = (ct.c_double * len(pyXTrain))(*pyXTrain)
YTrain = (ct.c_double * len(pyYTrain))(*pyYTrain)
inputCountPerSample = ct.c_int(pyInputCountPerSample)
sampleCount = ct.c_int(pySampleCount)
gamma = ct.c_double(pyGamma)
return myDll.fit_reg_RBF_naive(XTrain, gamma, YTrain, sampleCount, inputCountPerSample)
def predict_reg_RBF_naive(pyW, pyXTrain, pyXpredict ,pyInputCountPerSample, pyGamma, pySampleCount):
XTrain = (ct.c_double * len(pyXTrain))(*pyXTrain)
inputCountPerSample = ct.c_int(pyInputCountPerSample)
sampleCount = ct.c_int(pySampleCount)
gamma = ct.c_double(pyGamma)
Xpredict = (ct.c_double * len(pyXpredict))(*pyXpredict)
return myDll.predict_reg_RBF_naive(W, XTrain, Xpredict, inputCountPerSample, gamma, sampleCount)基本上,我加载我的DLL,为参数设置C类型,并为我的两个字体设置结果。然后,我制作了一个python包装器,这样用户就不必重新键入从python到cpp的每个强制转换。
我在cpp方面的类型似乎也不错:
extern "C" {
SUPEREXPORT double predict_reg_RBF_naive(double* W, double* X, double* Xpredict, int inputCountPerSample, double gamma, int N);
SUPEREXPORT double* fit_reg_RBF_naive(double* XTrain, double gamma, double* YTrain, int sampleCount, int inputCountPerSample);
}我没有收到编译器对cpp部分的警告,我在从cpp返回fit_reg_RBF_naive和python中的W之前打印了内存adresse,它们是相同的。
000002B358384980 // cpp address of W before return
0x58384980 # Python address of W after function call对我来说似乎是同一个地址。也许我错了。
所以当我试图调用我的第二个cpp函数时,它说
myDll.predict_reg_RBF_naive(W,XTrain,Xpredict,inputCountPerSample,gamma,sampleCount) OSError:异常:读取0x0000000000007C7380A0的访问冲突
当它试图读取W时,它在cpp中崩溃。它们不是cpp中的free或“delete”,变量被正确分配:double* W = new double[2];
另外,当我在python中打印W类型时,我得到了<class 'int'>。
为什么我的W在语言方面似乎有相同的地址,但是没有好的类型?将fit_reg_RBF_naive的结果类型更改为POINTER(ct.c_double * 2)不会发生任何更改。
编辑:
以下是我如何调用我的函数:
from dll_load import predict_reg_RBF_naive, fit_reg_RBF_naive
gamma = 50
sampleCount = 2
inputCountPerSample = 3
XTrain = [1.0, 1.0, 1.0, 3.0, 3.0, 3.0]
YTrain = [-1.0, 1.0]
Xpredict = [1.0, 1.0, 1.0]
W = fit_reg_RBF_naive(XTrain, gamma, YTrain, sampleCount, inputCountPerSample)
print(predict_reg_RBF_naive(W, XTrain, Xpredict, inputCountPerSample, gamma, sampleCount))发布于 2019-06-11 06:18:52
[Python3.Docs]:ctypes Python的外部函数库。
您拼错了restype__的(应该是restype)。这样做,restype就不会被初始化,默认为int (这在32位上不会有问题),您会遇到:
除此之外,代码中还有几个问题:
double*),则不要使用ctypes.c_void_p (在argtype或restype中)来映射它,因为它可能太宽,而是使用(本例中的) ctypes.POINTER(ctypes.c_double)E 229。ctypes不知道如何将Python转换为ctypes.POINTER(ctypes.c_double) (或ctypes.c_void_p),转换必须手动进行(到ctypes.c_double数组):
XTrain = 1.0、1.0、1.0、3.0、3.0、3.0 xtrain_ctypes = (ctypes.c_double *len(XTrain))(*x列)
并将xtrain_ctypes传递给函数。https://stackoverflow.com/questions/56533843
复制相似问题