Я пытаюсь создать простую программу связывания Fortran-C, но я застрял в довольно простой концепции - вывод значения из переменной-члена.
Несмотря на то, что я установил значение 5,Я получаю случайные числа обратно - очевидно, проблема с памятью. Кажется, что проблема заключается в методе print_vsize()
, но я понятия не имею, что здесь может быть не так.
Я также попытался посмотреть на instance
в режиме отладки, и кажется, чтов классе строится некоторая внутренняя структура:
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)