Неверное значение читается из переменной класса Fortran - PullRequest
3 голосов
/ 25 октября 2019

Я пытаюсь создать простую программу связывания Fortran-C, но я застрял в довольно простой концепции - вывод значения из переменной-члена.

Несмотря на то, что я установил значение 5,Я получаю случайные числа обратно - очевидно, проблема с памятью. Кажется, что проблема заключается в методе print_vsize(), но я понятия не имею, что здесь может быть не так.

Я также попытался посмотреть на instance в режиме отладки, и кажется, чтов классе строится некоторая внутренняя структура:

enter image description here

1) Не могли бы вы дать какие-либо советы о том, что может быть не так смой код?

2) Можно ли применить тот же принцип для массивов, передаваемых в качестве параметров?


main.f90

program test
    use iso_c_binding
    use myclassbind

    implicit none

    type(myclass) :: instance


    instance = myclass(5)
    call instance%print_vsize()

end program test

myClass_c_mod.f90

module myclassbind
    use iso_c_binding

    implicit none

    private
    public :: myclass

    type myclass
        private
        type(c_ptr) :: ptr

    contains
        procedure :: print_vsize => print_vsize_impl
    end type

    interface myclass
        module procedure create_myclass
    end interface

    interface

        function create_myclass_c(n) bind(C, name="create_myclass_c")
            use iso_c_binding
            implicit none

            type(c_ptr) :: create_myclass_c
            integer(c_int), value :: n
        end function

        subroutine print_vsize_c(obj) bind(C, name="print_vsize_c")
            use iso_c_binding
            implicit none
            type(c_ptr) :: obj
        end subroutine print_vsize_c
    end interface

contains

    function create_myclass(n)
        implicit none
        type(myclass) :: create_myclass
        integer(c_int), intent(in) :: n
        create_myclass%ptr = create_myclass_c(n)
    end function

    subroutine print_vsize_impl(this)
        implicit none
        class(myclass) :: this
        call print_vsize_c(this%ptr)
    end subroutine print_vsize_impl
end module

myClass_c.h

#ifndef FORTRANBIND_MYCLASS_C_H
#define FORTRANBIND_MYCLASS_C_H

#ifdef __cplusplus
extern "C" {
    class myClass;
    typedef myClass MYCLASS;
#else
    typedef struct MYCLASS MYCLASS;
#endif

    MYCLASS* create_myclass_c(int n);
    void print_vsize_c(MYCLASS* obj_ptr);

#ifdef __cplusplus
}
#endif

#endif //FORTRANBIND_MYCLASS_C_H

myClass_c.cpp

#include <vector>

#include "myClass.h"
#include "myClass_c.h"

MYCLASS* create_myclass_c(int n) {
    return new myClass(n);
}

void print_vsize_c(MYCLASS* obj_ptr) {
    obj_ptr->print_vsize();
}

myClass.h

#ifndef FORTRANBIND_MYCLASS_H
#define FORTRANBIND_MYCLASS_H

#include <iostream>
#include <vector>

class myClass {
private:
    int n;

public:
    explicit myClass(int n);
    void print_vsize();
};

#endif //FORTRANBIND_MYCLASS_H

myClass.cpp

#include "myClass.h"


myClass::myClass(int n) {
    this->n = n;
}

void myClass::print_vsize() {
    std::cout << this->n << std::endl;
}

CMakeLists.txt

CMAKE_MINIMUM_REQUIRED(VERSION 3.13)
PROJECT(FortranBind C CXX Fortran)

SET(CMAKE_CXX_STANDARD 17)
SET(CMAKE_Fortran_STANDARD 2008)

ADD_EXECUTABLE(FortranBind main.f90)
TARGET_LINK_LIBRARIES(FortranBind PUBLIC myClass_c_mod )

ADD_LIBRARY(myClass_c_mod myClass_c_mod.f90 myClass.cpp myClass_c.cpp)

...