Python 如何从C++;在赛顿班里面? 我正在学习Cython,我正在尝试定义一个类,它使用了我创建的C++函数。在读了将近两天的文档并尝试之后,我总是有一个错误。这是错误跟踪: /home/rubiales/Desktop/Projects/General/venv-General/compiler_compat/ld: build/temp.linux-x86_64-3.7/random.o: in function `int std::uniform_int_distribution<int>::operator()<std::mersenne_twister_engine<unsigned long, 32ul, 624ul, 397ul, 31ul, 2567483615ul, 11ul, 4294967295ul, 7ul, 2636928640ul, 15ul, 4022730752ul, 18ul, 1812433253ul> >(std::mersenne_twister_engine<unsigned long, 32ul, 624ul, 397ul, 31ul, 2567483615ul, 11ul, 4294967295ul, 7ul, 2636928640ul, 15ul, 4022730752ul, 18ul, 1812433253ul>&, std::uniform_int_distribution<int>::param_type const&)': /home/rubiales/Desktop/Projects/Route_optimizer/MTSPTW/algorithm/cython/GA/random.cpp:14: multiple definition of `_randuniform()'; build/temp.linux-x86_64-3.7/test_class.o:/home/rubiales/Desktop/Projects/Route_optimizer/MTSPTW/algorithm/cython/GA/random.cpp:14: first defined here /home/rubiales/Desktop/Projects/General/venv-General/compiler_compat/ld: build/temp.linux-x86_64-3.7/random.o: in function `_randint(int, int)': /home/rubiales/Desktop/Projects/Route_optimizer/MTSPTW/algorithm/cython/GA/random.cpp:22: multiple definition of `_randint(int, int)'; build/temp.linux-x86_64-3.7/test_class.o:/home/rubiales/Desktop/Projects/Route_optimizer/MTSPTW/algorithm/cython/GA/random.cpp:22: first defined here collect2: error: ld returned 1 exit status error: command 'g++' failed with exit status 1

Python 如何从C++;在赛顿班里面? 我正在学习Cython,我正在尝试定义一个类,它使用了我创建的C++函数。在读了将近两天的文档并尝试之后,我总是有一个错误。这是错误跟踪: /home/rubiales/Desktop/Projects/General/venv-General/compiler_compat/ld: build/temp.linux-x86_64-3.7/random.o: in function `int std::uniform_int_distribution<int>::operator()<std::mersenne_twister_engine<unsigned long, 32ul, 624ul, 397ul, 31ul, 2567483615ul, 11ul, 4294967295ul, 7ul, 2636928640ul, 15ul, 4022730752ul, 18ul, 1812433253ul> >(std::mersenne_twister_engine<unsigned long, 32ul, 624ul, 397ul, 31ul, 2567483615ul, 11ul, 4294967295ul, 7ul, 2636928640ul, 15ul, 4022730752ul, 18ul, 1812433253ul>&, std::uniform_int_distribution<int>::param_type const&)': /home/rubiales/Desktop/Projects/Route_optimizer/MTSPTW/algorithm/cython/GA/random.cpp:14: multiple definition of `_randuniform()'; build/temp.linux-x86_64-3.7/test_class.o:/home/rubiales/Desktop/Projects/Route_optimizer/MTSPTW/algorithm/cython/GA/random.cpp:14: first defined here /home/rubiales/Desktop/Projects/General/venv-General/compiler_compat/ld: build/temp.linux-x86_64-3.7/random.o: in function `_randint(int, int)': /home/rubiales/Desktop/Projects/Route_optimizer/MTSPTW/algorithm/cython/GA/random.cpp:22: multiple definition of `_randint(int, int)'; build/temp.linux-x86_64-3.7/test_class.o:/home/rubiales/Desktop/Projects/Route_optimizer/MTSPTW/algorithm/cython/GA/random.cpp:22: first defined here collect2: error: ld returned 1 exit status error: command 'g++' failed with exit status 1,python,c++,cython,Python,C++,Cython,这是我的Cython类:测试类.pyx: # random_builder.pyx # distutils: language = c++ # distutils: sources = random.cpp import numpy as np cimport numpy as np import cython cdef extern from "random.cpp": cdef float _randuniform() cdef int _randint

这是我的Cython类:
测试类.pyx

# random_builder.pyx
# distutils: language = c++
# distutils: sources = random.cpp
import numpy as np
cimport numpy as np
import cython

cdef extern from "random.cpp":
    cdef float _randuniform()
    cdef int _randint(int min_val, int max_val)


cdef class RandomClass():
    cdef:
        int a, b
    def __init__(self, int a, int b):
        self.a = a
        self.b = b

    cpdef float randf(self):
        return _randuniform()

    cpdef int randi(self):
        return _randint(self.a, self.b)

两个C++函数:<代码>随机。CPP < /代码> < /P>

#ifndef RANDOM_CPP
#define RANDOM_CPP
#include <Python.h>
#include <iostream>
#include <functional>
#include <iterator>
#include <algorithm>
#include <random>
#include <numeric>


using namespace std;

float _randuniform(){
    std::random_device rand_dev;
    std::mt19937 generator(rand_dev());
    std::uniform_real_distribution<float>  distr(0, 1);

    return distr(generator);
}

int _randint(int min_val, int max_val){
    std::random_device rd;     // only used once to initialise (seed) engine
    std::mt19937 rng(rd());    // random-number engine used (Mersenne-Twister in this case)
    std::uniform_int_distribution<int> uni(min_val,max_val); // guaranteed unbiased

    int random_integer = uni(rng);
    return random_integer;
}

#endif 
如果使用C++编译器,CPP文件工作正常。 我尝试在类内部导入函数,使用
.self()
,也在类的方法内部导入函数,以及其他未成功的事情。我认为这个错误跟踪是我最近一次让它工作


谢谢你的帮助。

\define RANDOM\u CPP
需要在
\defind RANDOM\u CPP
之后才能进行投票-投票以typo.DavidW结束,我也会这么说,但是在.CPP文件中包含这些预处理器语句难道不奇怪吗?“如果在任何地方,它们不应该在标题中吗?”菲德尔斯蒂克斯同意。将cpp文件直接包含到Cython文件中通常是一个有用的快捷方式(如果您不需要在任何地方共享定义),但是是的-我不会在那里使用include guards。很抱歉,我输入了一个错误,因为我将原始类更改为另一个更容易再现错误的类,是的,跟踪更改,我已经更新了我的Question@RubialesAlberto如果您执行“直接导入cpp”快捷方式,那么也不要将其添加到列表中以在setup.py中编译-您要编译它两次,这就是为什么会得到多个定义。不过,使用头文件更好
#ifndef RANDOM_CPP
#define RANDOM_CPP
#include <Python.h>
#include <iostream>
#include <functional>
#include <iterator>
#include <algorithm>
#include <random>
#include <numeric>


using namespace std;

float _randuniform(){
    std::random_device rand_dev;
    std::mt19937 generator(rand_dev());
    std::uniform_real_distribution<float>  distr(0, 1);

    return distr(generator);
}

int _randint(int min_val, int max_val){
    std::random_device rd;     // only used once to initialise (seed) engine
    std::mt19937 rng(rd());    // random-number engine used (Mersenne-Twister in this case)
    std::uniform_int_distribution<int> uni(min_val,max_val); // guaranteed unbiased

    int random_integer = uni(rng);
    return random_integer;
}

#endif 
from setuptools import Extension, setup
from Cython.Build import cythonize

setup(ext_modules = cythonize(Extension(
           "test_class",                                # the extension name
           sources=["test_class.pyx", "random.cpp"], # the Cython source and
                                                  # additional C++ source files
           language="c++",                        # generate and compile C++ code
      )))