我目前正在尝试为一些C++代码编写一个简单的包装器,这样我就能够传入一些信号数据,对其进行图形处理器操作,然后将其发送回来。目前,我已经删除了所有GPU元素,因为我无法让ctype返回除整数以外的任何内容。
我应该在下面的前言中说,我不确定这个决定的严重性,但我只能通过将C++函数包装在C函数中来使ctype识别C++函数。随着我尝试返回浮点数的不幸经历的继续,我已经意识到无论错误的来源是什么,都可以明确地区分来自C++的数字和来自C的数字之间的区别。我稍后会回到这一点。
extern "C" float* giveLotsZeroes(int length) {
float* list2 = (float*)malloc(sizeof(float)*length);
for (unsigned int i = 0; i < length; i++) list2[i] = 0;
return list2;
}
这是我在"kernal.cu“文件中用来测试返回浮点数的功能的示例C++函数之一。它被传递给C,在"chead.h“中定义了extern float* giveLotsZeroes(int length);
和__declspec(dllexport) float* giveLotsOfZeroes(int length);
(注意函数名中间的,以区分它们)。最后,float* giveLotsOfZeroes(int length) { return giveLotsZeroes(length); }
是在包括chead.h的Source.c中定义的,链接器似乎可以将其编译成多线程dll。我有一个类似的迭代,它以整数的形式返回一个0列表,它的功能非常好,以至于我在GPU错误处理中实现了它,并且由于GPU代码的每一行似乎都会导致错误,我有理由相信错误处理实现工作得很好,但我稍后会介绍一个异常。
在尝试返回长度为128的整数列表时,我使用numpy的ctypeslib库非常成功,
accelerator.getLastErrorCode.restype = np.ctypeslib.ndpointer(dtype=ctypes.c_int,shape=(128,))
accelerator.getLastLineExecuted.restype = np.ctypeslib.ndpointer(dtype=ctypes.c_int,shape=(128,))
但是,如果我用长度变量" length“替换128,用ctypes.c_float替换ctypes.c_int,python通常会返回一个介于1e8和1e10之间的整数。对于如此奇怪的结果,我也尝试了返回单个浮点数,这也产生了类似的结果,尽管人们可能会认为单值函数也返回单个值,而不是那么惊人。有趣的是,当我使用定义restypes的np.ctypeslib.ndpointer方法时,python type
函数仍然声称结果是一个numpy.ndarray
,但是如果你把它当作一个restypes来处理,就会报错。我曾尝试将此函数的restypes
或函数的变体定义为ctypes.c_float*length
或ctypes.POINTER(ctypes.c_float*length)
,但都没有成功。
事实上,我做了两个返回单个零的函数,一个从C++返回到C再返回到python,另一个直接从C返回,并让这两个函数将它们的零打印到控制台以确认C没有问题,也没有C++的0有问题,但是当它们到达python时,C的0变成了1(我后来发现无论C试图返回什么都是这种情况),C++的0变成了一致的164。一位朋友建议将每个0
实例更改为0.0f
,这会将164更改为标准随机大数。
我在错误处理方面遇到的唯一问题是,在一个奇特但可重复的奇怪实例中,700
设法从一个应该只能返回0到29之间的数字的函数中出来。不确定这可能与其他错误有什么联系,但如果它有帮助,它就会有帮助。
我已经将我的代码包含在下面的pastebin中,但请注意,python代码的大部分只是测试什么能按预期工作,什么不能工作。
发布于 2020-03-24 20:55:50
返回值为ctypes.POINTER(ctypes.c_float)
>>> from ctypes import *
>>> dll = CDLL('test')
>>> dll.giveLotsZeroes.argtypes = c_int,
>>> dll.giveLotsZeroes.restype = POINTER(c_float)
>>> x = dll.giveLotsZeroes(100)
>>> x
<__main__.LP_c_float object at 0x0000022DE407F948>
>>> x[0]
0.0
>>> x[99]
0.0
您还可以使用以下命令获取整个数组的边界检查:
>>> a = cast(x,POINTER(c_float*100)).contents
>>> a
<__main__.c_float_Array_100 object at 0x0000022DE45A5CC8>
>>> a[0]
0.0
>>> a[99]
0.0
>>> a[100]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: invalid index
转换为Python列表:
>>> list(a)
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
https://stackoverflow.com/questions/60788664
复制相似问题