问题描述
我在将字符数组从 C++ 传递到 fortran (f90) 时遇到问题.
I am having trouble passing char arrays from c++ to fortran (f90).
这是我的 C++ 文件,'cmain.cxx':
Here is my c++ file, 'cmain.cxx':
#include <iostream>
using namespace std;
extern "C" int ftest_( char (*string)[4] );
int main() {
char string[2][4];
strcpy(string[0],"abc");
strcpy(string[1],"xyz");
cout << "c++: string[0] = '" << string[0] << "'" << endl;
cout << "c++: string[1] = '" << string[1] << "'" << endl;
ftest_(string);
return 0;
}
这是我的 Fortran 文件ftest.f90":
Here is my fortran file, 'ftest.f90':
SUBROUTINE FTEST(string)
CHARACTER*3 string(2)
CHARACTER*3 expected(2)
data expected(1)/'abc'/
data expected(2)/'xyz'/
DO i=1,2
WRITE(6,10) i,string(i)
10 FORMAT("fortran: string(",i1,") = '", a, "'" )
IF(string(i).eq.expected(i)) THEN
WRITE(6,20) string(i),expected(i)
20 FORMAT("'",a,"' equals '",a,"'")
ELSE
WRITE(6,30) string(i),expected(i)
30 FORMAT("'",a,"' does not equal '",a,"'")
END IF
ENDDO
RETURN
END
构建过程是:
gfortran -c -m64 ftest.f90
g++ -c cmain.cxx
gfortran -m64 -lstdc++ -gnofor_main -o test ftest.o cmain.o
请注意,也可以通过以下方式构建可执行文件:
note that the executable can also be build via:
g++ -lgfortran -o test ftest.o cmain.o
此外,当我运行 OSX 10.6 时,需要 -m64 标志.
Also, the -m64 flag is required as I am running OSX 10.6.
执行'test'的输出是:
The output from executing 'test' is:
c++: string[0] = 'abc'
c++: string[1] = 'xyz'
fortran: string(1) = 'abc'
'abc' equals 'abc'
fortran: string(2) = 'xy'
'xy' does not equal 'xyz'
在 ftest.f90 中声明大小为 4 的 'string' 和 'expected' 字符数组,即:
Declaring the 'string' and 'expected' character arrays in ftest.f90 with size 4, ie:
CHARACTER*4 string(2)
CHARACTER*4 expected(2)
并重新编译给出以下输出:
and recompiling gives the following output:
c++: string[0] = 'abc'
c++: string[1] = 'xyz'
fortran: string(1) = 'abc'
'abc' does not equal 'abc '
fortran: string(2) = 'xyz'
'xyz' does not equal 'xyz '
在'cmain.cxx'中声明大小为3的字符数组,即:
Declaring the character arrays in 'cmain.cxx' with size 3, ie:
extern "C" int ftest_( char (*string)[3] );
int main() {
char string[2][3];
并恢复到 fortran 文件 (3) 中的原始大小,即:
and reverting to the original size in the fortran file (3), ie:
CHARACTER*3 string(2)
CHARACTER*3 expected(2)
并重新编译给出以下输出:
and recompiling gives the following output:
c++: string[0] = 'abcxyz'
c++: string[1] = 'xyz'
fortran: string(1) = 'abc'
'abc' equals 'abc'
fortran: string(2) = 'xyz'
'xyz' equals 'xyz'
所以最后一种情况是唯一有效的情况,但在这里我已将 3 个字符分配给大小为 3 的字符数组,这意味着缺少终止 '\0',并导致输出 'abcxyz' - 这是对于我的预期应用不可接受.
So the last case is the only one that works, but here I have assigned 3 characters to a char array of size 3 which means the terminating '\0' is missing, and leads to the 'abcxyz' output - this is not acceptable for my intended application.
任何帮助将不胜感激,这让我发疯!
Any help would be greatly appreciated, this is driving me nuts!
推荐答案
C 字符串以零结尾,而 Fortran 字符串,按照惯例,用空格填充但大小固定.您不应该指望无需转换就能将 C 字符串传递给 fortran.
C strings are zero terminated whereas fortran strings, by convention, are space padded but of fixed size. You shouldn't expect to be able to pass C strings to fortran without some conversion.
例如:
#include <algorithm>
void ConvertToFortran(char* fstring, std::size_t fstring_len,
const char* cstring)
{
std::size_t inlen = std::strlen(cstring);
std::size_t cpylen = std::min(inlen, fstring_len);
if (inlen > fstring_len)
{
// TODO: truncation error or warning
}
std::copy(cstring, cstring + cpylen, fstring);
std::fill(fstring + cpylen, fstring + fstring_len, ' ');
}
然后您可以将其与 ftest
的 3 或 4 长度版本一起使用:
Which you can then use with either the 3 or 4 length version of ftest
:
#include <iostream>
#include <ostream>
extern "C" int ftest_( char string[][4] );
void ConvertToFortran(char* fstring, std::size_t fstring_len,
const char* cstring);
int main()
{
char cstring[2][4] = { "abc", "xyz" };
char string[2][4];
ConvertToFortran(string[0], sizeof string[0], cstring[0]);
ConvertToFortran(string[1], sizeof string[1], cstring[1]);
std::cout << "c++: string[0] = '" << cstring[0] << "'" << std::endl;
std::cout << "c++: string[1] = '" << cstring[1] << "'" << std::endl;
ftest_(string);
return 0;
}
这篇关于将字符数组从 C++ 传递到 Fortran的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!