Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c++ > #91693

Re: Problem with calling C++ from Fortran

From Ben Bacarisse <ben.usenet@bsb.me.uk>
Newsgroups comp.lang.c++
Subject Re: Problem with calling C++ from Fortran
Date 2023-09-12 00:26 +0100
Organization A noiseless patient Spider
Message-ID <87cyyoqoka.fsf@bsb.me.uk> (permalink)
References <udhbs9$e5d$1@dont-email.me> <udhcaj$j8l$1@dont-email.me> <udkdu9$itm4$1@dont-email.me> <87o7iajh8b.fsf@bsb.me.uk> <udmvg7$11r4u$1@dont-email.me>

Show all headers | View raw


db <dieterhansbritz@gmail.com> writes:

> On 10.09.2023 15.22, Ben Bacarisse wrote:
>> db <dieterhansbritz@gmail.com> writes:
>> 
>>> On 09.09.2023 11.02, Muttley@dastardlyhq.com wrote:
>>>> On Sat, 9 Sep 2023 10:54:33 +0200
>>>> db <dieterhansbritz@gmail.com> wrote:
>>>>> but now it says that C-double doesn't exist.
>>>>>
>>>>> Any ideas?
>>>> C++ mangles function names so that the name you give the function isn't
>>>> the
>>>> name the dynamic loader sees in the binary. You need to put this around whatever
>>>> function you want to call from Fortran so it has C style linkage which means
>>>> the name remains the same:
>>>> extern "C" {
>>>> void calledFromFortran()
>>>> {
>>>> 	:
>>>> }
>>>> }
>>>>
>>> Where should this go in the code? I added it at the end as is,
>>> and now I get this:
>>>
>>> ~/ownlib90/tests> ./jbandtest
>>> jband.cpp:88:1: error: expected initializer before 'extern'
>>>     88 | extern "C" {
>>>        | ^~~~~~
>>> jband.cpp:96:1: error: expected unqualified-id before '{' token
>>>     96 | {
>>>        | ^
>>> jband.cpp: In function 'void calledFromFortran()':
>>> jband.cpp:350:9: error: expected primary-expression before ':' token
>>>    350 |         :
>>>   ...
>> You are giving people very little to go on.  There's an unknown command
>> (./jbandtest) the gives some errors where only one line of code can be
>> seen.
>> Can you produce a cut-down version to the program that shows the same
>> error --  mimimal example of the C++ and of the Fortran that should
>> calls it but which fails?  That would mean you could post the code.
>> If that is not possible, can you link to the source so those who know
>> both C++ and Fortran can take a proper look?
>
> I put the C++ function here: www.dieterbritz.dk/jband.cpp
> After getting errors about the extern lines, whch I had
> added at the end, I shifted it to near the start:
>
> #include <iostream>
> #include <fstream>
> #include <iomanip>
> #include "math.h"
>
> using namespace std;
>
> extern "C" {
>
> void calledFromFortran()
> {
>         :
> }
>
> }

Remove them all.  You have two options.  One: correct the C++.  To do
this put this, and only this,

extern "C" {
   const long double iband(const long double tbar);
}

just after the #include lines.  This is perfect (the first const is a
meaningless word here and the compiler may warn you about that) but it
will do.

Next replace

#include "math.h"

with

#include <math.h>

I'd also remove the two unnecessary #include lines (for iomanip and
fstream).  All of these are "tidying up".  Only the extern "C" part I
gave corrects an actual mistake.

The second option is the turn the code in C which links directly with
Fortran.  The only C++ used by the code is one "cout << " line (not a
good way to report an error, but that's not important right now) and a
setting for pi that is not a compile-time constant (4*atanl(1)) written
in a more fussy way.

To convert to C, copy the file to jband.c (rather than .cpp) and replce
the declaration for pi.  Given the code is littered with explicit 21
digits decimals (a little more than the precision of C's usualy long
double type) I would just write

static const long double pi = 3.14159265358979323846L;

Now replace the cout line with

   fputs("\nError in stredges::iband(): tbar must be > 0", stderr);

This writes the message to the error stream and put only these two
include lines at the top:

#include <math.h>
#include <stdio.h>

Now the file is C code.

Frankly, this is the way I'd go, since linking C is just that bit
simpler than linking C++.  But if the code is going to become fully
fledged (and complex) C++, obviously use my first option.

> I still get errors pertaining to these lines. But after adding
> the -c to the two compilation lines in the script, these are
> now the only errors. I think I am getting closer. The errors
> are now

Yes, you must compile it like this:

g++ -c jband.cpp     (for C++ code)
gcc -c jband.c       (for C code)

You don't need any -o but you could add in lots of warnings like

gcc -Wall -Wextra -c jband.c

> jband.cpp: In function 'void calledFromFortran()':
> jband.cpp:12:9: error: expected primary-expression before ':' token
>    12 |         :
>       |         ^
> jband.cpp: At global scope:
> jband.cpp:96:1: error: expected initializer before 'extern'
>    96 | extern "C" {
>       | ^~~~~~
> jband.cpp:104:1: error: expected unqualified-id before '{' token
>   104 | {
>       | ^
> jbandtest.f90:28:14:
>
>    28 |   FORTJBAND = JBAND (tbar)
>       |              1
> Error: Type mismatch in argument 'tbar' at (1); passed REAL(16) to REAL(10)
>
> The last error will go away together with the others.

Michael S has given you one way to go for that.  My comments were going
to be more general.  You have several ways of specifying the types, and
I could not tell if you really wanted all of them.  In general, I would
define the Fortran types from the C ones (since those are the types you
need for the call and return) and leave it at that.

But the big one is that the Fortran code seems to think the function is
called jband, when in fact it's called iband.

I went for this:

module STUFF
  use iso_c_binding
  integer, parameter :: qud=real(c_long_double)
end module STUFF
program JBAND_TEST
  use STUFF;   implicit none
  real(qud) :: tbar, curr, FORTJBAND
  do
     read *, tbar
     if (tbar < 0) exit
     curr = FORTJBAND (tbar)
     print '(" curr =", f10.4)', curr
  enddo
end program JBAND_TEST

function FORTJBAND (tbar)
  use STUFF;   implicit none
  interface
     function IBAND (tbar) bind(c)
       use STUFF
       real(qud), VALUE :: tbar
       real(qud) :: IBAND
    end function iband
  end interface
  real(qud) :: FORTJBAND, tbar
  FORTJBAND = IBAND(tbar)
end function FORTJBAND

Note that you can compile the Fortran along with the C at the same time
if you like:

$ gfortran -o jtest jbandtest.f90 jband.c -lm
$ ./jtest
1
 curr =    1.5224
1e-10
 curr =56419.9584
-1
$

($ is my Linux command-line prompt).  I have no idea if these are
correct results and I can't be sure what you need to run on your system,
but the code links and appears to work.

If you go with the C++ option, the linking needs the standard C++
library:

$ gfortran -o jtest jbandtest.f90 jband.cpp -lstdc++ -lm
$ ./jtest
1
 curr =    1.5224
1e-10
 curr =56419.9584
-1
$

BTW, you said the C++ was written by a C++ expert.  I don't think it
was!

-- 
Ben.

Back to comp.lang.c++ | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread


Thread

Problem with calling C++ from Fortran db <dieterhansbritz@gmail.com> - 2023-09-09 10:54 +0200
  Re: Problem with calling C++ from Fortran Muttley@dastardlyhq.com - 2023-09-09 09:02 +0000
    Re: Problem with calling C++ from Fortran db <dieterhansbritz@gmail.com> - 2023-09-09 12:47 +0200
      Re: Problem with calling C++ from Fortran Muttley@dastardlyhq.com - 2023-09-09 10:51 +0000
      Re: Problem with calling C++ from Fortran db <dieterhansbritz@gmail.com> - 2023-09-09 12:52 +0200
        Re: Problem with calling C++ from Fortran Muttley@dastardlyhq.com - 2023-09-09 11:00 +0000
          Re: Problem with calling C++ from Fortran db <dieterhansbritz@gmail.com> - 2023-09-10 14:33 +0200
            Re: Problem with calling C++ from Fortran Paavo Helde <eesnimi@osa.pri.ee> - 2023-09-10 18:49 +0300
            Re: Problem with calling C++ from Fortran Muttley@dastardlyhq.com - 2023-09-11 08:23 +0000
        Re: Problem with calling C++ from Fortran Paavo Helde <eesnimi@osa.pri.ee> - 2023-09-09 16:56 +0300
          Re: Problem with calling C++ from Fortran db <dieterhansbritz@gmail.com> - 2023-09-10 14:36 +0200
          Re: Problem with calling C++ from Fortran James Kuyper <jameskuyper@alumni.caltech.edu> - 2023-09-11 00:14 -0400
        Re: Problem with calling C++ from Fortran Bo Persson <bo@bo-persson.se> - 2023-09-10 16:08 +0200
      Re: Problem with calling C++ from Fortran "Alf P. Steinbach" <alf.p.steinbach@gmail.com> - 2023-09-09 16:30 +0200
    Re: Problem with calling C++ from Fortran db <dieterhansbritz@gmail.com> - 2023-09-10 14:48 +0200
      Re: Problem with calling C++ from Fortran Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-09-10 14:22 +0100
        Re: Problem with calling C++ from Fortran Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-09-10 17:27 +0100
        Re: Problem with calling C++ from Fortran db <dieterhansbritz@gmail.com> - 2023-09-11 14:00 +0200
          Re: Problem with calling C++ from Fortran Michael S <already5chosen@yahoo.com> - 2023-09-11 05:21 -0700
          Re: Problem with calling C++ from Fortran Muttley@dastardlyhq.com - 2023-09-11 13:33 +0000
          Re: Problem with calling C++ from Fortran Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-09-12 00:26 +0100
            Re: Problem with calling C++ from Fortran db <dieterhansbritz@gmail.com> - 2023-09-12 10:48 +0200
              Re: Problem with calling C++ from Fortran Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-09-12 14:14 +0100
              Re: Problem with calling C++ from Fortran Michael S <already5chosen@yahoo.com> - 2023-09-12 07:15 -0700
            Re: Problem with calling C++ from Fortran Michael S <already5chosen@yahoo.com> - 2023-09-12 02:00 -0700
              Re: Problem with calling C++ from Fortran Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-09-12 14:22 +0100
                Re: Problem with calling C++ from Fortran Michael S <already5chosen@yahoo.com> - 2023-09-12 07:32 -0700
                Re: Problem with calling C++ from Fortran db <dieterhansbritz@gmail.com> - 2023-09-12 18:36 +0200
                Re: Problem with calling C++ from Fortran Michael S <already5chosen@yahoo.com> - 2023-09-19 02:39 -0700
  Re: Problem with calling C++ from Fortran Michael S <already5chosen@yahoo.com> - 2023-09-10 08:38 -0700
  Re: Problem with calling C++ from Fortran Michael S <already5chosen@yahoo.com> - 2023-09-10 09:51 -0700
    Re: Problem with calling C++ from Fortran Michael S <already5chosen@yahoo.com> - 2023-09-11 02:49 -0700
  Buy Zen Mushroom Chocolate Bar Microdose "https://psychedelicminds.shop/" <psychedelicsmind@gmail.com> - 2023-09-11 05:14 -0700

csiph-web