简体   繁体   中英

Unknown type name 'PyModuleDef'

I'm working with Python and C++ integration, and I'm on MacOS.

When I use all of the PyObject methods they all seem to work but none of the PyModule methods seem to be working.

This is my code:

#include <iostream>
#include <cmath>
#include <vector>

#if PY_MAJOR_VERSION >= 3
#define PY3K
#endif

#ifdef __APPLE__
#include <Python/Python.h>
#else
#include <Python.h>
#endif

#define space " "
#define epoch int(1000)

using namespace std;

double hypothesis(const std::vector<double>& b_val, double x){
    return b_val[0] + b_val[1] * x;
}

std::vector<double> regression(const std::vector<double>& x, const std::vector<double>& y,
                               int epochs, double learning_rate){
    if(!epochs) epochs = epoch;
    double _m = 0;
    double _b = 0;
    std::vector<double> _values(2);
    int N = x.size();

    for(int i = 0; i < epochs; i++){
        _values[0] = _b, _values[1] = _m;
        double dm = 0;
        double db = 0;
        double cost = 0;

        for(int j = 0; j < N; j++){
            double p = hypothesis(_values, x[j]);
            cost += pow(y[j] - p, 2);
            dm += (-2.0 / N) * (x[j] * (y[j] - p));
            db += (-2.0 / N) * (y[j] - p);
        }

        cost /= N;
        _m = _m - (learning_rate * dm);
        _b = _b - (learning_rate * db);

        if ((i + 1) % 100 == 0)
            std::cout << "Epoch: " << (i + 1) << " Cost: " << cost << std::endl;
    }
    std::vector<double> result(2);
    result[0] = _m, result[1] = _b;
    return result;
}

static PyObject * fit(PyObject * self, PyObject * args){
    PyObject *x;
    PyObject *y;
    double learning_rate;
    int epochs;
    int N;

    if(!PyArg_ParseTuple(args, "00di0i", &x, &y, &epochs, &learning_rate, &N)){
        return nullptr;
    }

    std::vector<double> _x(N), _y(N);
    for(int i = 0; i < N; i++){
        _x[i] = PyFloat_AsDouble(PyList_GetItem(x, (Py_ssize_t)i));
        _y[i] = PyFloat_AsDouble(PyList_GetItem(y, (Py_ssize_t)i));
    }

    std::vector<double> _result = regression(_x, _y, epochs, learning_rate);
    PyObject *result = PyTuple_New(2);
    for(int i = 0; i < 2; i++){
        PyTuple_SetItem(result, i, PyFloat_FromDouble(_result[i]));
    }

    return Py_BuildValue("s", result);
}

static PyMethodDef linreg_methods[] = {
        {"fit", (PyCFunction)fit, METH_VARARGS, "Linear Regression"},
        {nullptr}
};

static PyModuleDef linear_regression = {
        PyModuleDef_HEAD_INIT,
        "linear_regression"
        "Linear Regression",
        -1,
        linreg_methods
};

PyMODINIT_FUNC PyInit_linear_regression(void){
    return PyModule_Create(&linear_regression);
}

The output I get is error: unknown type name 'PyModuleDef' .

I can't seem to understand what the problem is.

You will need to make sure the included Python.h is from the Python3.x build, and that you link to the corresponding library, for example, on Linux that would be:

g++ my_module.cpp -I/usr/include/python3.8/ -lpython3.8

But on MacOS this file would be dependent on where/how you installed Python3. You should be able to use locate Python.h and find the Python3 directory.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM