Я все еще начинаю программировать на C и C++. В настоящее время я разрабатываю код для вызова функции в C++ из C. Это связано с тем, что мой основной код написан на C, и мне нужно использовать определенную библиотеку, написанную в C++. Я использую библиотеку Eigen для этого подхода. У меня в настоящее время есть проблема, чтобы вернуть значение, которое было создано в C++, на C. Я хотел бы вернуть (A) из *.cpp в *.c и просмотреть результат (printf) в *.c.
Вот мои примеры кода.
Основной код в main.c
#include "lib2run.h"
#include "stdio.h"
int main ()
{
struct C_MatrixXd *matrix1;
matrix1 = play_matrix ();
printf("Here is matrix1:\n");
MatrixXd_print(matrix1); // <-- I want to use printf to print matrix1, not like this
return 0;
}
Заголовочный файл lib2run.h
#ifdef __cplusplus
extern "C"
{
#endif
struct C_MatrixXd* play_matrix ();
void MatrixXd_print (const struct C_MatrixXd *m);
#ifdef __cplusplus
} // end extern "C"
#endif
Вот код в lib2run.cpp
#include <iostream>
#include <Eigenvalues>
#include <Core>
#include "lib2run.h"
using namespace Eigen;
using Eigen::MatrixXd;
using Eigen::EigenSolver;
inline C_MatrixXd* eigen_to_c(MatrixXd& ref)
{
return reinterpret_cast<C_MatrixXd*>(&ref);
}
inline MatrixXd& c_to_eigen(C_MatrixXd* ptr)
{
return *reinterpret_cast<MatrixXd*>(ptr);
}
inline const MatrixXd& c_to_eigen(const C_MatrixXd* ptr)
{
return *reinterpret_cast<const MatrixXd*>(ptr);
}
C_MatrixXd* play_matrix ()
{
MatrixXd A = MatrixXd::Random(3,3);
std::cout << "Here is a random 3x3 matrix, A:" << std::endl << A << std::endl << std::endl;
EigenSolver<MatrixXd> es(A);
MatrixXd D = es.pseudoEigenvalueMatrix();
MatrixXd V = es.pseudoEigenvectors();
std::cout << "The pseudo-eigenvalue matrix D is:" << std::endl << D << std::endl<< std::endl;
std::cout << "The pseudo-eigenvector matrix V is:" << std::endl << V << std::endl<< std::endl;
std::cout << "Finally, V * D * V^(-1) = " << std::endl << V * D * V.inverse() << std::endl<< std::endl;
return eigen_to_c (A);
}
void MatrixXd_print(const C_MatrixXd *m)
{
std::cout << c_to_eigen(m) << std::endl;
}
C и C++ живут счастливо вместе. Проблема заключается в том, что указывает @jxh. Вы возвращаете указатель на объект, который не будет существовать при использовании точки. В вашем случае, и чтобы изменить свой код как можно меньше, вы должны использовать new
для выделения MatrixA.
// Allocate a new matrix which will live beyond this function
MatrixXd* A = new MatrixXd(3,3);
// Copy a random matrix to it
*A = MatrixXd::Random(3,3);
// ...
return A;
Если вы также можете изменить свой main.c
на main.cpp
и скомпилировать с компилятором C++ (например, g++), а затем сменить C_MatrixXd.
printf
для печати матрицы», как это. Что вы можете сделать, это (в части C ++) вызвать член.data()
матрицы, чтобы получить указатель на непрерывный массив, содержащий данные, передать его в код C и затем выполнить цикл по нему,printf()
каждый стоимость. Я не думаю, что вы сделаете себе одолжение с этим. Eigen был действительно разработан как библиотека C ++. Если вы в основном пишете на C, вам, вероятно, следует вместо этого использовать традиционный интерфейс BLAS / LAPACK (или перенести весь ваш код на C ++, как сказал @NeilKirk).