Fortran 将字符*81 数组传递给 C/C++ 代码
fortran pass character*81 array to c/c++ code
我是编程新手,我想在我的 c++ 代码中调用一个 fortran 函数。 问题是我不知道如何将 fortran 字符 *81 数组传递给我的 c++。
Fortran代码是这样的:
subroutine func01(a)
implicit none
character*81 a(2)
write(*,*) a(1)
write(*,*) a(2)
end
C++ 代码如下所示:
#include <iostream>
extern "C"{
void func01_( const char **a );
}
int main()
{
const char *a[2];
a[0]="Hello world!";
a[1]="This is a test!";
func01_(a);
return 0;
}
我用这个对我的 fortran 代码进行了基本测试
program pro01
character*81 a(2)
a(1)='Hello world!'
a(2)='This is a test!'
call func01(a)
end program pro01
'func01(a(' 效果很好。
多亏了@PaulMcKenzie,我纠正了一些愚蠢的问题.....
但是,当我编译 cpp 代码时,结果就像混乱的代码一样,例如:
7
@L
@��n��@�UH�j��FP
@��n���U�շ�=��U�ྼ��� @��
我该怎么办?
以下代码似乎适用于 Linux(x86_64( 上的 gcc4,但不清楚它是否也适用于其他平台。(如上所述,现代Fortran的C互操作性可能是有用的。
函数01.f90
subroutine func01( a )
character(*) :: a( 2 )
print *
print *, "char length = ", len(a(1)), len(a(2))
print *, "raw a(1) : [", a(1), "]"
print *, "raw a(2) : [", a(2), "]"
print *, "trim : [", trim(a(1)), "] [", trim(a(2)), "]"
end
主.cpp
extern "C" {
void func01_( char *c, const int len );
}
#include <iostream>
#include <cstring> // for memset()
int main()
{
const int lenmax = 30, numstr = 3; // changed char length to 30 to fit in the terminal
char a[ numstr ][ lenmax ];
std::string str[ numstr ];
str[0] = "moon"; str[1] = "mercury"; str[2] = "jupiter";
for( int k = 0; k < numstr; k++ ) {
memset( a[k], ' ', lenmax ); // fill space
str[k].copy( a[k], lenmax ); // copy at most lenmax char (no attached)
}
func01_( a[0], lenmax );
func01_( a[1], lenmax ); // pass from mercury
return 0;
}
编译
$ g++ func01.f90 main.cpp -lgfortran
结果
char length = 30 30
raw a(1) : [moon ]
raw a(2) : [mercury ]
trim : [moon] [mercury]
char length = 30 30
raw a(1) : [mercury ]
raw a(2) : [jupiter ]
trim : [mercury] [jupiter]
这是一个可移植的解决方案,用于将任意长度的字符串数组从 C 传递到 Fortran。
我使用了一个与您自己的文件非常相似的C++文件:
#include <iostream>
extern "C" void func01(const char **a);
int main()
{
const char *a[2] = {"Hello World","This is a test"};
func01(a);
return 0;
}
上面唯一的变化是字符数组的初始化和删除 Fortran 函数的不那么便携的下划线。 相反,我们将使用 Fortran 2003 提供的标准 C 互操作性。 func01
的 Fortran 实现变为:
subroutine func01(cstrings) bind(C,name="func01")
use, intrinsic :: iso_c_binding, only: c_ptr, c_char, c_f_pointer
implicit none
type(c_ptr), dimension(2), target, intent(in) :: cstrings
character(kind=c_char), pointer :: a1(:), a2(:)
! size_t strlen(char * s);
interface
function strlen(s) bind(C, name='strlen')
use, intrinsic :: iso_c_binding, only: c_ptr, c_size_t
implicit none
type(c_ptr), intent(in), value :: s
integer(c_size_t) :: strlen
end function strlen
end interface
call c_f_pointer(cstrings(1), a1, [strlen(cstrings(1))])
call c_f_pointer(cstrings(2), a2, [strlen(cstrings(2))])
write (*,*) a1
write (*,*) a2
end subroutine func01
bind
属性使我们与 C 的函数名称具有互操作性,并且我们对变量使用 C 类型。 变量 cstrings
将采用 2 个指针的数组,或者在 C、*[2]
或 **
中。 该过程的大部分是一个接口块,它允许我们调用标准 C 库例程,strlen
通过以下对 c_f_pointer
的调用使我们的生活更轻松,将 C 指针转换为 Fortran 指针。
编译并运行时,输出如预期的那样是:
$ ./string-array-test
Hello World
This is a test
使用 gcc 5.1.0 编译和测试。
相关文章:
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 代码在main()中运行,但在函数中出现错误
- 在VS代码中交叉编译Windows与Linux上的MinGW的SDL程序
- 编译包含字符串的代码时遇到问题
- 我在c++代码中生成了一个运行时#3异常
- 如何在linux终端中同时编译和运行c++代码
- 为cl.exe(Visual Studio代码)指定命令行C++版本
- 在Linux for Windows上编译C++代码时出错
- 我的字符计数代码计算错误.为什么
- 孤立代码块在结构中引发异常
- 在编译C++代码(具有dlib和opencv)到WASM时面临问题
- 为什么我的C#代码在调用回C++COM直到Task时会暂停.等待/线程.加入
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- 此代码是否违反一个定义规则
- 为什么我的代码在输出中增加了93天
- 我的简单if-else语句是如何无法访问的代码
- 使用动态分配的数组会导致代码分析发出虚假的C6386缓冲区溢出警告
- 为什么在这个代码结束循环中没有得到结束
- 在c代码之间共享数据的最佳方式
- 这个指针和内存代码打印是什么?我不知道是打印垃圾还是如何打印我需要的值