我是C ++的新手,所以对任何愚蠢的人都道歉。错误。
我在C ++中创建了一个用于Python的共享对象。但是,当我尝试在Python中调用此函数时,内核崩溃了。
C ++文件如下:
#include <cmath>
#include <iostream>
#include <list>
#include <vector>
using namespace std;
extern "C"
{
vector<int> cplusplus(int n=3,int maximum=1000)
{
int i,j,order,m,i1,i2,mag;
vector<int> output(0);
i=1;
j=0;
while (i/maximum<=1)
{
i=10*i;
j=j+1;
}
m=j-1;
for (i1=1; i1<m+2; i1++)
{
mag=pow(10,(i1-1));
i=0;
while (i+mag*(n+1)<=maximum)
{
for (i2=i+mag*n; i2<i+mag*(n+1); i2++)
{
output.push_back(i2-1);
}
i=i+10*mag;
}
if(i+mag*(n+1)>maximum)
{
for (i2=i+mag*n; i2<maximum+1; i2++)
{
output.push_back(i2-1);
}
}
}
return output;
}
}
我使用:
创建.so文件g++ -shared -o cplusplus.so cplusplus.cpp
我用Python调用C ++函数:
import ctypes
cpp=ctypes.cdll.LoadLibrary('/Users/.../cplusplus.so')
print cpp.cplusplus(n=3,maximum=1000)
当正确返回时,该函数应该返回1到1000之间包含3(即3,13,23,30,31,...)的所有数字的向量。但是,目前Python内核崩溃了。
我认为这与我在C ++文件中使用向量或内存泄漏有关。
提前感谢您的帮助!
答案 0 :(得分:1)
ctypes
不了解C ++类型,因此这里是一个在函数接口中仅使用C类型的函数版本。必须预先分配结果缓冲区,并按地址传入元素的数量。该函数使用计算向量的长度更新元素的数量,如果它可以将这些元素复制到结果缓冲区中,则返回1(成功),否则返回0(失败)。
请注意,代码算法不正确并返回错误的答案,但ctypes有效。
#include <cmath>
#include <iostream>
#include <list>
#include <vector>
using namespace std;
extern "C"
{
__declspec(dllexport) int cplusplus(int n, int maximum, int* result, size_t* pLength)
{
int i, j, order, m, i1, i2, mag;
vector<int> output(0);
i = 1;
j = 0;
while(i / maximum <= 1)
{
i = 10 * i;
j = j + 1;
}
m = j - 1;
for(i1 = 1; i1 < m + 2; i1++)
{
mag = pow(10, (i1 - 1));
i = 0;
while(i + mag * (n + 1) <= maximum)
{
for(i2 = i + mag * n; i2 < i + mag * (n + 1); i2++)
output.push_back(i2 - 1);
i = i + 10 * mag;
}
if(i + mag * (n + 1) > maximum)
{
for(i2 = i + mag * n; i2 < maximum + 1; i2++)
output.push_back(i2 - 1);
}
}
if(output.size() > *pLength)
{
*pLength = output.size();
return 0; // fail
}
*pLength = output.size();
memcpy(result, output.data(), output.size() * sizeof(int));
return 1; // success
}
}
>>> from ctypes import * >>> lib = CDLL('test') >>> lib.cplusplus.argtypes = c_int,c_int,POINTER(c_int),POINTER(c_size_t) >>> lib.cplusplus.restype = c_int >>> arr = (c_int * 1000)() >>> size = c_size_t(1000) >>> lib.cplusplus(3,1000,arr,byref(size)) 1 >>> size c_ulonglong(300) >>> list(arr[:size.value]) [2, 12, 22, 32, 42, 52, 62, 72, 82, 92, 102, 112, 122, 132, 142, 152, 162, 172, 182, 192, 202, 212, 222, 232, 242, 252, 262, 272, 282, 292, 302, 312, 322, 332, 342, 352, 362, 372, 382, 392, 402, 412, 422, 432, 442, 452, 462, 472, 482, 492, 502, 512, 522, 532, 542, 552, 562, 572, 582, 592, 602, 612, 622, 632, 642, 652, 662, 672, 682, 692, 702, 712, 722, 732, 742, 752, 762, 772, 782, 792, 802, 812, 822, 832, 842, 852, 862, 872, 882, 892, 902, 912, 922, 932, 942, 952, 962, 972, 982, 992, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398] >>> size = c_size_t(200) # too small >>> lib.cplusplus(3,1000,arr,byref(size)) 0 >>> size c_ulonglong(300)
答案 1 :(得分:0)
我想知道n和max是否是实际变量。试试吧:
Print cpp.cplusplus ()
尝试构建一个在c ++中显示向量的方法。所以你没有混合印刷语言方法。
答案 2 :(得分:0)
你需要告诉python你的函数的输入和返回类型是modular inverse。我很确定std :: vector不是选项的一部分,选项列在文档中。
这不是最快的最佳做法选项 我开始做的是将你的输入序列化为json,并将它们作为char_p传递给共享库,然后用c ++转换它们,并返回另一个char_p ......但当然这不是最快或最好的选项。
(如果您确实正确定义了类型,请编辑您的帖子,我将删除此答案)