gpt4 book ai didi

python - 错误的 ctypes 分配

转载 作者:行者123 更新时间:2023-11-30 04:46:49 25 4
gpt4 key购买 nike

我制作了一个 CPP DLL,并尝试从 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,为我的两个函数设置参数和结果的 Ctypes。然后我制作了一个 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 部分,我没有收到来自编译器的警告,我已经在返回之前打印了内存地址 fit_reg_RBF_naive来自 cpp 和 W在 python 中,它们是相同的。

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: exception: access violation reading 0x000000007C7380A0

它在尝试读取 W 时在 cpp 中崩溃了.他们不是 free或在 cpp 中“删除”并且变量已正确分配:double* W = new double[2];

此外,当我打印 W 时输入 python 我得到 <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))

最佳答案

[Python 3.Docs]: ctypes - A foreign function library for Python .

您拼错了 restypes(应该是 restype)。通过这样做,restype 没有被初始化,并且默认为 int(这在 32bit 上不是问题),你遇到了:

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

  • 如果 C 函数指定了一个指针(在这种情况下为 double*),不要使用 ctypes.c_void_p(在 argtypesrestype) 来映射它,因为它可能太宽了,使用(对于这种情况)ctypes.POINTER(ctypes.c_double) 代替
  • 对我来说,这甚至无法编译(我想知道您是如何运行该代码的)。我将仅在 XTrain 上举例说明,但也适用于 YTrainXpredictctypes 不知道将 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))(*XTrain)

    并将 xtrain_ctypes 传递给函数。

关于python - 错误的 ctypes 分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56533843/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com