Как использовать функцию 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