My main program is C++ and I need to use modules of an existing Fortran program. I was able to link to it with g++.
Problem is, all subroutines inside the fortran codes are designed to be called by a Fortran main program. Globally, the initialization of global variables in the latter is done by directing an input file on command line:
main_fortran_prog < inputFile.ext
A given subroutine "foubar" require these variables to be set. For that, It reads from unit identifier 5 which is, according to documentation I read, for INPUT from the keyboard with the READ statement.
Now, I want to call the subroutine "foubar" in my C++ main which will initialize theses variables "real_fou" and "bool_flag" before the subroutine operation. Knowing that "foubar" will look out the value of real_fou and bool_flag in namelist from unit identifier 5 which I'm trying to avoid, what are the best options for me?
In sum: I want to migrate from a Fortran main to a C++ main. I'm trying avoid namelist reading from a file if possible.
List of files in my directory:
inputFile.ext:
! this file is used by fortran main program to initialize global variable
&justANamelist
real_fou = 0.3490834
bool_flag = .true.
/
afortmodule.f90
module afortmodule
implicit none
integer :: ios
logical, save :: bool_flag
real, save :: real_fou
contains
subroutine foubar() bind(c, name='foubar')
use iso_c_binding
call parseInput
write(*,*) "real_fou x 2 = " , real_fou * 2
end subroutine
subroutine parseInput
! Define the namelist
NAMELIST /justANamelist/ real_fou, bool_flag
! How to bypass this in cpp call ?
read(5,nml=justANamelist, IOSTAT=ios)
end subroutine
end module afortmodule
main_fortran.f90
! require < inputFile.ext
program mainfortranprog
use afortmodule
! call foubar to display real_fou x 2
call foubar
end program mainfortranprog
main_cpp.cpp
// This want to call the subroutine foubar in fortran module afort_module
// like main_fortran did but avoiding the commandline input like "< inputFile.ext"
#include <iostream>
using namespace std;
void call_foubar(void);
extern "C"{
void foubar (void);
bool bool_flag;
double real_fou;
}
int main (void){
real_fou = 3.13215163;
bool_flag = true;
//How can I use these values in namelist justANamelist
//in manner that I could be able to do:
call_foubar();
return 0;
}
void call_foubar(void){
// some codes here
foubar();
}
Related
This question already has answers here:
How do I pass a 2D array in C++ to a Fortran subroutine?
(4 answers)
Segmentation fault occurs at top of subroutine when C code calls Fortran subroutine
(2 answers)
segmentation fault when calling fortran subroutine in C++
(2 answers)
Closed 1 year ago.
I know similar questions have already been answered however I did not find exact help for my problem. In C++ I have an array double pf[2][4] and I want to pass it to a Fortran 95 subroutine which shall overwrite the entries and then return it.
How do I have to declare this array in my c++ file when Fortran follows a column-major order unlike c++? My naive first try just leaving it as above resulted in a segmentation fault error.
Originally the code has been entirely in Fortran and the corresponding array was declared as REAL*8 P(0:3,4) and I am searching how to give the subroutine an array in this form while declaring it in C++.
The code of the subroutine can be found here: https://www.pp.rhul.ac.uk/~cowan/computing/tutorial99/rambo.f
SUBROUTINE RAMBO(N,ET,XM,P,WT,LW)
IMPLICIT REAL*8(A-H,O-Z) AAFU0020
DIMENSION XM(N),P(4,N),Q(4,100),Z(100),R(4), AAFU0021
. B(3),P2(100),XM2(100),E(100),V(100),IWARN(5) AAFU0022
...
It generates four-momenta for particles in collider events which obey momentum conservation and on-shellness.
Here is my c++ code in which I really just want to declare the array and call the subroutine to fill it with values.
#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;
extern "C"{ void rambo_(int n, double sqrts, const double mf[2], double pf[4][4], double fwgt);}
double integrand(double pf[4][4]){
double p1[4],p2[4],fwgt; //declaration four vectors and weight
//constants
const double sqrts = 2000;
const double mf[2]={0,173}; //array with particle masses
rambo_(2,sqrts,mf,pf,fwgt);
return 0;
}
int main(){
double pf[4][4];
double x = integrand(pf);
std::cout << std::fixed;
std::cout << std::setprecision(16);
std::cout << "Msquared = " << x << endl;
}
I link the files via
gfortran -c rambo.f
g++ -c demo1.cpp
g++ demo1.o rambo.o -o demo -lgfortran
Running ./demo returns Segmentation fault (core dumped). Thanks for any help!
In my main matlab function, some m functions written by myself and some built-in matlab functions are called. If I use the maltab compiler mcc to compile these called m functions to be a C++ library, and also compile the main matlab function, is it possible that I could call this main function in my C++ scripts ? Or how could I achieve this goal? Is it a must to convert the main matlab function to a C++ function? Any help will be appreciated.
Here is an example to explain my question more clearly:
function y = mymain(m,n)
...
a = randn(m,n);
b = find(a>0);
c = sqrt(b);
d = myfun1(b);
e = myfun2(c); % myfun1 and myfun2 are the subfunctions written by my self
...
% in myfun1 and myfun2, only the matlab build-in functions are called.
% my goal is to get the point that a C++ main function could call this mymain
My goal is to fill an open array by C++. The stage is as follows.
1. SV: Define a sized unpacked array and send it via open array in the import function.
2. C++: Fill the open array.
3. SV: Use the array.
For the sized unpacked array, there is no problem. But in real situation the array size is changed often and the compiled C++ function must be recompiled each time. To avoid this situation, I need to use an open array so that the C function check the size and fill the data accordingly.
In the following, the sources are simplified showing only the essential parts. The import function svcpp called at SV and executed in C++. The arguments are the open array i[], whose handle is h in C++ side. When I compile the C++ source, the error occurs,
"error LNK1120: unresolved externals".
What is the problem?
SV side:
module
import "DPI-C" context function void svcpp (inout byte unsigned i[]);
byte myarray[2];
initial
svcpp(myarray);
endmodule
C++ side:
#include "svdpi.h"
#include "dpiheader.h"// This includes the data structure for the open array
void svcpp(const svOpenArrayHandle h){
//*(uchar *) x = *(uchar *) svGetArrElemPtr(h,0);
*(uchar *) svGetArrElemPtr(h,1) = 10; //I really want this operation.
}
You might try this to avoid the C++ compiler from mangling the name of your function.
extern "C" void svcpp(const svOpenArrayHandle h) {
...
}
I'm still new to this kind of extending (though I've a good background in C++ and python)
what I wanted is to use ctypes module to pass data to a C++ function
example that worked so far for me:
test.dll file
#define DLLEXPORT extern "C" __declspec(dllexport)
DLLEXPORT int sum(int a, int b) {
return a + b;
}
sum_test.py file:
from ctypes import cdll
mydll = cdll.LoadLibrary('test.dll')
mydll.sum(5, 3)
result is 8 which works well...
note:
I'm using this to develop an Addon(plugin) for blender, the data which I will pass to the C++ function is a huge array (Tuple or whatever type of array), this data will be passed to GPU to process it with OpenCL
mainly the workflow in C++ is passing a pointer (which will copy the whole array data to the GPU)
so the question is:
the best way (fastest too) to get that tuple pointer inside C++ (hopefully with explaining what happens in python and in C++)
The easiest way is to tell ctypes that the function takes a pointer to an array of a certain type, in many cases Python/ctypes will figure out the rest.
libc = CDLL('libc.so.6') # on Debian/Linux
printf = libc.printf
printf.restype = c_int
printf.argtypes = [POINTER(c_char), c_int]
printf('< %08x >', 1234)
This assumes that the function will simply take a pointer. If your function takes for example exactly five floats, you could provide c_float * 5 as according parameter type.
I am debugging prog.f90, which has a module mod.f90.
How do I print the argument variable values?
The module has a subroutine that gets called within a loop. It takes in the arguments, stores one in a local variable, calculates the new value of the argument, stores that in another local variable, then uses the local variables to test a certain condition. The new value of the argument gets passed back to main.
I am trying to print the values of all the variables while within the subroutine.
I can print the local variables, but printing the argument variables gives me a reference address.
(gdb)print temp_curr
$1 = 4
(gdb)print arg1
$2 = (REF TO -> ( real8 )) #0x7fffffffe0a0: -nan(0x8000000000000)
I tried...
(gdb)print $arg1
$3 = VOID
The subroutine looks something like this...
SUBROUTINE sub(arg1, arg2)
IMPLICIT NONE
REAL, INTENT(inout):: arg1, arg2
REAL :: temp_prev, temp_curr
temp_prev = arg1
arg1 = (a bunch of calculations)/arg2
temp_curr = arg1
IF (temp_curr < temp_prev) THEN
stop
END IF
END SUBROUTINE sub
The $arg1 variable in gdb is used only in gdb scrips (see GDB documentation). If you refer to the variable of the program being debugged use only arg1.
Try print MODULENAME::VARNAME if you want to print a variable (VARNAME) from another module (MODULENAME)