圈重点:
1. 谁分配,谁释放。不要 Fortran 分配 C 释放,或者 C 分配,Fortran释放。
2. Fortran指针转换成 C 指针,会丢失长度。需要额外的参数传递或约定来存储长度,以便释放的时候使用。
3. C 指针转换成 Fortran 指针,需要补上长度。
4. 下方的注释可以参考。
[C++] 纯文本查看 复制代码 extern "C" void cf_test1( char**); //不要写 stdcall, Fortran用 Bind(C 捆绑的函数是 cdecl 协定的
extern "C" void free_test( char * , int n );
extern "C" void cf_test2(char*,int n);
#include <stdio.h>
int main() {
char* var = nullptr;
cf_test1(&var); //由 Fortran 分配
printf("%s\n\n\n",var);
free_test(var,10000000); // 由 Fortran 释放
var = new char[10000000];//由C分配
cf_test2(var,10000000); //Fortran 只负责赋值
printf("%s\n\n\n",var);
delete[]var;//由C释放
return 0;
}
[Fortran] 纯文本查看 复制代码 module f2c
use, intrinsic :: iso_c_binding
implicit none
contains
subroutine cf_test1(ps_list) BIND(C,Name="cf_test1")!//由 Fortran 分配
!DEC$ ATTRIBUTES DLLEXPORT :: cf_test1
!implicit none //多余
type(C_PTR) :: ps_list
character(len=:) , pointer :: m_list
allocate( character(len=10000000)::m_list ) !//先分配
ps_list = c_loc(m_list) !//分配后把 Fortran 指针转换成 C 指针
m_list = repeat("FOR",1000) // C_NULL_CHAR
end subroutine
subroutine cf_test2(ps_list,n) BIND(C,Name="cf_test2")!//由C分配
!DEC$ ATTRIBUTES DLLEXPORT :: cf_test2
!implicit none //多余
type(C_PTR) , value :: ps_list
integer , value :: n
character(len=n), pointer :: s_list
call c_f_pointer( ps_list , s_list ) !//先 C 指针转换成 Fortran 指针,再赋值
s_list = repeat("CCC",1000) // C_NULL_CHAR
end subroutine
subroutine free_test(ps_list,n) BIND(C,Name="free_test")
!DEC$ ATTRIBUTES DLLEXPORT :: free_test
!implicit none //多余
type(C_PTR) , value :: ps_list
integer , value :: n
character(len=n), pointer :: s_list
call c_f_pointer( ps_list , s_list ) !//先把 C 指针还原(转换)成 Fortran 指针,再释放
deallocate(s_list)
end subroutine
end module
|