passing char arrays from c++ to fortran

前端 未结 3 448
鱼传尺愫
鱼传尺愫 2020-12-17 02:23

I am having trouble passing char arrays from c++ to fortran (f90).

Here is my c++ file, \'cmain.cxx\':

#include 

using namespace std         


        
相关标签:
3条回答
  • 2020-12-17 02:45

    The examples given are far too heavyweight, as long as you don't want to pass more than one string you can make use of the "hidden" length parameter ...

    extern "C" void function_( const char* s, size_t len )  {  
      std::string some_string( s, 0, len );
      /// do your stuff here ...
      std::cout << "using string " << some_string << std::endl;
      /// ...
    
    }
    

    which you can call from fortran like

      call function( "some string or other" )
    

    You don't need to faff about with individual copy operations, since the std::string constructor can do all that for you.

    0 讨论(0)
  • 2020-12-17 02:49

    I recommend using the ISO C Binding on the Fortran side as suggested by "High Performance Mark". You are already using "extern C". The ISO C Binding of Fortran 2003 (currently implemented in most Fortran 95 / partial Fortan 2003 compilers) makes this a compiler and platform independent approach. Charles Bailey described the differences between strings in the two languages. This Stackoverflow question has a code example: Calling a FORTRAN subroutine from C

    If you don't want to modify existing Fortran code you could write a "glue" routine in between your C++ code and the existing Fortran code. Writing the glue routine in Fortran using the ISO C Binding would be more reliable and stable since this would be based on the features of a language standard.

    0 讨论(0)
  • 2020-12-17 03:02

    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.

    For example:

    #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, ' ');
    }
    

    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;
    }
    
    0 讨论(0)
提交回复
热议问题