Как использовать функцию Cython в C++

Я пытаюсь использовать функцию, которую я создал и скомпилировал с использованием Cython в коде C++. Другими словами, я хочу сделать эту функцию доступной из C/++ через файл.c, который компилирует Cython. Я прочитал из вызова функции Cython из C++, что это возможно с помощью ключевого слова public. Вот мой код LQR.pyx:

from __future__ import division, print_function

import numpy as np
import scipy.linalg
import math

cdef float g = 9.80665
cdef float m = 1.430
cdef float l = 0.2475

cdef float IzzP = 0.0000976065
cdef float Ixx = 0.014592865
cdef float Iyy = 0.015714325
cdef float Izz = 0.028431714  

cdef float p_bar = 0.
cdef float q_bar = 8.2207
cdef float r_bar = 12.2176

cdef float nx_bar = 0.
cdef float ny_bar = 0.5583
cdef float nz_bar = 0.8297

cdef float f1_bar = 4.9951
cdef float f2_bar = 6.9124
cdef float f3_bar = 4.9951

cdef float w1_bar = 667.4095
cdef float w2_bar = 794.5627
cdef float w3_bar = 667.4095

A_bar = ((Izz - Iyy)/Ixx) * r_bar + (IzzP/Ixx) * (w1_bar - w2_bar + w3_bar)
B_bar = ((Ixx - Izz)/Iyy) * r_bar - (IzzP/Iyy) * (w1_bar - w2_bar + w3_bar)

A = np.array([[0., A_bar, 0., 0.],
             [-B_bar, 0., 0., 0.],
             [0., -nz_bar, 0., r_bar],
             [nz_bar, 0., -r_bar, 0]])
B = np.array([[0., l/Ixx],
             [l/Iyy, 0.],
             [0., 0.],
             [0., 0.]])
C = np.identity(4, dtype=float)
D = np.zeros((4,2), dtype=float)

Q = np.array([[1., 0., 0., 0.],
             [0., 1., 0., 0.],
             [0., 0., 20., 0.],
             [0., 0., 0., 20.]])
R = np.identity(2, dtype=float)

cdef public float * LQR_Rib(float p, float q, float nx, float ny):
    cdef float p_til = p - p_bar
    cdef float q_til = q - q_bar
    cdef float nx_til = nx - nx_bar
    cdef float ny_til = ny - ny_bar

    X = np.matrix(scipy.linalg.solve_continuous_are(A, B, Q, R))
    K = np.matrix(scipy.linalg.inv(R)*(B.T*X))
    u = -K*np.array([[p_til],
                     [q_til],
                     [nx_til],
                     [ny_til]])

    cdef float forces[3]
    forces[0] = (2*f1_bar-u[0]-u[1])/2
    forces[1] = f2_bar + u[1]
    forces[2] = (2*f3_bar+u[0]-u[1])/2

    return forces

Я скомпилировал это в LQR.c и LQR.h, запустив этот код Python, который я назвал setup.py:

from distutils.core import setup

from Cython.Build import cythonize

setup(name="LQR",ext_modules=cythonize("LQR.pyx"))

Теперь я создал функцию C++ с именем dummy.cpp, которая обращается к LQR_Rib:

#include <stdio.h>
#include "LQR.h"

int main(){
    float *forces;
    forces = LQR_Rib(0, 0, 0, 0);
    printf("%f   %f   %f\n",forces[0], forces[1], forces[2]);
    return 0;
}

Когда я компилирую dummy.cpp, используя

g++ dummy.cpp -o dummy

Я получаю следующую ошибку:

In file included from dummy.cpp:2:
LQR.h:29:1: error: 'PyMODINIT_FUNC' does not name a type
 PyMODINIT_FUNC initLQR(void);
 ^~~~~~~~~~~~~~

Изменить: следуя предложению @lightalchemist, я добавил строку

#include <Python/Python.h> 

в верхней части файла LQR.h, созданного Cython. Теперь я получаю другую ошибку при компиляции dummy.cpp:

Undefined symbols for architecture x86_64:
  "_LQR_Rib", referenced from:
      _main in ccAX6DLo.o
ld: symbol(s) not found for architecture x86_64
collect2: error: ld returned 1 exit status

0 ответов

Другие вопросы по тегам