вернуть указатель из функции C ++ в функцию C

0

Я все еще начинаю программировать на C и C++. В настоящее время я разрабатываю код для вызова функции в C++ из C. Это связано с тем, что мой основной код написан на C, и мне нужно использовать определенную библиотеку, написанную в C++. Я использую библиотеку Eigen для этого подхода. У меня в настоящее время есть проблема, чтобы вернуть значение, которое было создано в C++, на C. Я хотел бы вернуть (A) из *.cpp в *.c и просмотреть результат (printf) в *.c.

Вот мои примеры кода.

  1. Основной код в 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
  1. Вот код в 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;
     }
    
  • 1
    Было бы намного проще просто конвертировать ваш код C в C ++.
  • 1
    Вы не можете «использовать printf для печати матрицы», как это. Что вы можете сделать, это (в части C ++) вызвать член .data() матрицы, чтобы получить указатель на непрерывный массив, содержащий данные, передать его в код C и затем выполнить цикл по нему, printf() каждый стоимость. Я не думаю, что вы сделаете себе одолжение с этим. Eigen был действительно разработан как библиотека C ++. Если вы в основном пишете на C, вам, вероятно, следует вместо этого использовать традиционный интерфейс BLAS / LAPACK (или перенести весь ваш код на C ++, как сказал @NeilKirk).
Показать ещё 2 комментария
Теги:

1 ответ

0

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.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню