在Python(2.7.12)ctypes中返回数组:第一次运行的结果不正确,从第二次运行开始没有问题 我有一个C++函数,我希望你在python 2.7.12中调用,看起来像: extern "C" { double* myfunction(double* &y, double* &z, int a, int b) { vector<double> _x; vector<double> _y; vector<double> _z; // Call some external C++ function cpp_function(_x, _y, _z, a, b); // Convert vectors back to arrays double* x = &_x[0]; // or x = _x.data(); y = &_y[0]; z = &_z[0]; return x; } }
在Python(2.7.12)ctypes中返回数组:第一次运行的结果不正确,从第二次运行开始没有问题 我有一个C++函数,我希望你在python 2.7.12中调用,看起来像: extern "C" { double* myfunction(double* &y, double* &z, int a, int b) { vector<double> _x; vector<double> _y; vector<double> _z; // Call some external C++ function cpp_function(_x, _y, _z, a, b); // Convert vectors back to arrays double* x = &_x[0]; // or x = _x.data(); y = &_y[0]; z = &_z[0]; return x; } },python,python-2.7,ctypes,Python,Python 2.7,Ctypes,X的每列和每行的总和应为1 运行我获得的Python脚本: 列和 [1.00000000 E+000 1.38691247e-309 1.65267271e-315 1.25888994e-315 6.283497888E-316 1.44468811e-315 1.00000000 E+000 6.30543835e-316 1.65486616e-315 6.30543094e-316 4.20365893e-316 1.39823788e-315 1.00000000 E+000 4.20
X
的每列和每行的总和应为1
运行我获得的Python脚本:
列和
[1.00000000 E+000 1.38691247e-309 1.65267271e-315
1.25888994e-315
6.283497888E-316 1.44468811e-315 1.00000000 E+000 6.30543835e-316
1.65486616e-315 6.30543094e-316 4.20365893e-316 1.39823788e-315
1.00000000 E+000 4.20363294e-316 1.49114498e-315 6.93457613e-310
1.00000000 E+000 1.28096634e-315]
行上求和
[1.00000000e+0001.00000000e+0001.00000000e+0006.99111970e-316
6.99111495e-316 6.99111021e-316 1.00000000 E+000 6.93459588e-310
3.78325942e-315 2.45135624e-315 3.71670210e-316 5.81849688e-316
5.81849807e-316 3.71670210e-316 5.81849925e-316 5.81850044e-316
6.93456516e-310 5.30598164e-316]
第二次运行它:
列和
[1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1]
行上求和
[1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1]
我的数据和函数是确定性的。从第二次开始的所有跑步都给出了相同的结果。该问题仅在第一次运行时出现(例如,如果我向脚本添加注释并再次运行,则会出现问题)
在Python 3.5.2中不会出现此问题。不幸的是,我必须在Python 2.7.12环境中使用该函数:(
我的问题:这个问题有解决办法吗
非常感谢您的帮助!
myfunction.argtypes=()
这显然是错误的。请检查有关放置内容的规范(或本网站上的其他示例)。另外double*&y
这看起来有点不自然。@CristiFati但它对我来说适用:(我认为问题并不是从这里来的。我尝试将argtypes
指定为myfunction.argtypes=[指针(c\u-double)、指针(c\u-double)、指针(c\u-int、c\u-int)]
但问题仍然存在:(对于c代码,double*&y
表示输入指针(或数组)将在函数中进行修改。它在Python 3中运行良好,因此我认为C代码中没有问题。感谢您的关注!即使某些东西运行正常,也没有理由出错。我知道C代码的意思,我只是说…(我会使用双指针)。然后这3个向量存储在堆栈上,当您退出函数时,它们将被删除,从而产生未定义的行为(或者至少,我认为是这样)@CristiFati谢谢。你能更具体地说明你会怎么做吗?我还是不明白。顺便说一下,由于你的评论,我意识到我忘了返回y
和z
(我没有注意到这一点,因为我在Python代码中没有使用y
和z
)例如,我说过我使用了double**y
,但我认为这与此无关。但问题是堆栈上的数组。要纠正这一点,您可以声明一些静态变量,也可以在堆上分配它们(但随后您将负责释放它们)。此外,我不认为传递byref(c_double())
就可以了。
from ctypes import *
libc = CDLL('myfunction.so')
myfunction = libc.myfunction
myfunction.argtypes = ()
myfunction.restype = POINTER(c_double)
y = c_double()
z = c_double()
a = 18
b = 18
x = myfunction(byref(y), byref(z), c_int(a), c_int(b))
X = np.asarray([x[i] for i in range(a*b)])
X = X.reshape((a, b))
# print sums over colums and over rows
print('sum over col')
print(np.sum(X, axis=0))
print('sum over row')
print(np.sum(X, axis=1))