首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >错误的ctype分配

错误的ctype分配
EN

Stack Overflow用户
提问于 2019-06-10 21:36:53
回答 1查看 67关注 0票数 1

我创建了一个CPP,并试图从python调用其中的函数。对于其他功能,我已经多次做到了,但是这个,我就是找不到我的错误。

代码语言:javascript
复制
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方面的类型似乎也不错:

代码语言:javascript
复制
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,它们是相同的。

代码语言:javascript
复制
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)不会发生任何更改。

编辑:

以下是我如何调用我的函数:

代码语言:javascript
复制
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))
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-06-11 06:18:52

[Python3.Docs]:ctypes Python的外部函数库

您拼错了restype__(应该是restype)。这样做,restype就不会被初始化,默认为int (这在32位上不会有问题),您会遇到:

除此之外,代码中还有几个问题:

  • 如果C函数指定了指针(本例中为double*),则不要使用ctypes.c_void_p (在argtype或restype中)来映射它,因为它可能太宽,而是使用(本例中的) ctypes.POINTER(ctypes.c_double)
  • 对我来说,这甚至没有编译(我想知道你是如何运行这段代码的)。我将仅在XTrain上举例说明,但适用于 YTrain Xpredict 以及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传递给函数。
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56533843

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档