Fortran subroutine called from Objective-C - objective-c

I am calling a fortran subroutine from a cocoa application.
The application is building with success and working as expected but I have this semantic issue : *
Implicit declaration of function "_increment" is invalid in C99
increment.o is the compiled fortran subroutine (gfortran compiler)
subroutine increment(n)
integer :: n
n=n+1
end subroutine increment
What am I doing wrong ?
Thank you for your help.

You have to declare the type of the function. Something like:
void increment_(int * i);
(In C, but I assume it is the same and I am guessing the correct signature, you do not show its code).
BTW, I recommend the Fortran subroutine as bind(C) or even bind(C,name="increment") and you do not have to use the trailing _.
Edit: try this
in the .m file:
void increment(int * i);
int the .f90 file:
subroutine increment(n) bind(C,name="increment")
use iso_c_binding
integer(c_int),intent(inout) :: n
n = n+1
end subroutine
If it does not help, try to use a debugger, or try some debugging print statements in the subroutine if loc(n) is equal to &i or whatever.

Related

Is "intent" guaranteed for contained subroutines inside a module contained subroutine?

I am wondering if the following code is legal:
module my_mod
contains
subroutine my_outer_sub(a)
integer, intent(in) :: a
call my_inner_sub()
contains
subroutine my_inner_sub()
a=3 ! this compiles and runs!
end subroutine my_inner_sub
end subroutine my_outer_sub
end module my_mod
I compiled the code with PGI 17.4. I have been using contained subroutines inside module subroutines and now I wonder if this scheme is a suitable one?
No, the code is illegal. You cannot modify an intent(in) argument. This is an error in the compiler and should be reported to your vendor.
Gfortran identifies it correctly
Error: Dummy argument 'a' with INTENT(IN) in variable definition context (assignment) at (1)
and so does Intel Fortran
intent3.f90(11): error #6780: A dummy argument with the INTENT(IN) attribute shall not be defined nor become undefined. [A]
a=3 ! this compiles and runs!
------^
compilation aborted for intent3.f90 (code 1)

Fortran link modules for precision and global variable types

I am new to Fortran and trying to understand if the following is possible. My idea to structure the program is to declare the precision and variable types in one module. Then make use of those variables without declaring again the type in other modules or the main program.
module pre
implicit none
INTEGER, PARAMETER :: sp=SELECTED_REAL_KIND(6,37)
INTEGER, PARAMETER :: dp=SELECTED_REAL_KIND(15,307)
INTEGER, PARAMETER :: qp=SELECTED_REAL_KIND(33,4931)
REAL(dp), PARAMETER :: pi = 4.*ATAN(1.)
REAL(dp) :: H
REAL(dp) :: M
REAL(dp) :: KR
end module pre
Now I want to make use of all the variables in another module that contains one or more functions, such as:
module hon
use pre
implicit none
contains
function KE(H,M) result(KR)
KR = 2*PI/H/M
end function KE
end module hon
Then I use gfortran in this order:
gfortran -c mod_pre.f90
gfortran -c mod_hon.f90
Since 'module pre' is part of 'module hon' I compile in order, but gfortran shows an error.
With the code above I understand the variable types and parameters should have been included by USE; But the message I get from gfortran is that none of my variables have IMPLICIT type when I try to compile 'module hon'.
Could somebody clarify the problem or suggest a solution? I would like to avoid having my variables scattered in multiple modules.
Thanks!
In the function statement, the result(kr) says that the function result has name kr. This function result is not the same thing as the module variable kr. In particular, this function result makes inaccessible the module variable.
The function result is specific to the function itself and its properties must be declared within the function subprogram.
Similarly, the dummy arguments of the function, H and M, are distinct from the module variables and need to be declared in the function subprogram.
Beyond that, you perhaps have similar concerns to this other question.
To be clear, it isn't possible to say something like "all function results called kr and all dummy arguments called H or M have these characteristics". Each individual object must be given the properties.
However, although I don't recommend this, this is a situation where literal text inclusion (using a preprocessor or include file) could help you:
function ke(H, M) result (kr)
include 'resdummydecls'
...
end function
where the file has the declarations.

Calling C dll from Fortran

How to call C DLL from Fortran? I don't code in Fortran but I need to do some testing on it.
Let say in the test.dll have functions:
Open()
Close()
How can I tell Fortran to use the test.dll?
I mean like C# we may use
[DllImport("test.dll")]
static extern uint Open();
I could not find any example that can help me. I would also prefer if you could provide a compiler that you use.
Update
I use Plato compiler.
I tried to load test.dll using this method. However, it popped up error message saying Error 29, Call to missing routine: _LOADLIBRARY
Here is the code. I found it online. So not sure if I'm doing it correctly.
program test
integer :: p
pointer :: q
p = loadlibrary ("test.dll"C) ! the C at the end says -
! add a null byte as in C
q = getprocaddress (p, "Open"C)
end
EDIT
Sorry. The DLL is using C and not C++

Externally declared (global) variable in Fortran

I want to know if it's possible to declare a variable and have declaration carry over to another subroutine or program (hence become global)
For example
program main
implicit none
call mysub
print *, x
end program main
subroutine mysub
implicit none
integer, parameter :: x = 1
end subroutine mysub
Would print "1"
Is this possible? I want to do this because a program I'm working on has large sets of variables that I would rather avoid copying unless necessary.
The most straightforward way to do this in modern Fortran is with modules.
Consider
module globals
implicit none
integer :: x
end module globals
program main
use globals
implicit none
call mysub
print *,x
end program main
subroutine mysub
use globals
implicit none
x = 1
end subroutine mysub
In this paradigm you specify your "global" variables within the module and use that module everywhere you want access to them.
If you are just using this to declare contants (parameters) you can simplify this to:
module globals
implicit none
integer, parameter :: x=1
end module globals
program main
use globals
implicit none
print *,x
end program main
The older method to accomplish this involved common blocks and includeing files that declared them every procedure that accessed them. If you find a tutorial dealing with the common block method I advise you to ignore them and avoid their use in new code.

Arbitray variable/array type in fortran functions/subroutines

I hope this is not a too stupid question, but is it possible to have functions or subroutines where I can pass the type of an array like
subroutine foo(array, arr_type)
implicit none
arr_type, dimension(:) :: array
*Do something with array*
end subroutine
or do I have to write a subroutine for each possible arr_type (e.g. integer, double precision,...) and overload the subroutine with an interface ?
Yes and no... You can bundle several functions/subroutines with different dummy arguments using an interface:
module foos
interface foo
module procedure foo_real
module procedure foo_int
end interface
contains
subroutine foo_real( a )
implicit none
real,intent(inout) :: a(:)
! ...
end subroutine
subroutine foo_int( a )
implicit none
integer,intent(inout) :: a(:)
! ...
end subroutine
end module
I know of no (simple) possibility to pass arrays with arbitrary basic type. You could take a look at transfer - but there be dragons ;-)
You could experiment with Fortran 2003's unlimited polymorphism. Write your subroutine a bit like this:
subroutine foo(array)
implicit none
class(*), dimension(:) :: array
! Do something with array
end subroutine
From the point of view of abbreviating code this won't save you much because you're likely to have to write something like
use, intrinsic :: iso_fortran_env, only : real32, real64
.
.
.
select type (element=>array(1))
type is (real(real32))
! Code for 32-bit reals
type is (real(real64))
! Code for 64-bit reals
type is (integer)
! Code for integers of default kind
class is (shape)
! Code for shapes
class default
! Sweep up everything else
end select
But you may end up writing as many lines as if you follow Alexander Vogt's entirely sensible approach.
EDIT, after comments
What this approach won't deliver, because Fortran doesn't include its intrinsic types in any sort of type hierarchy, is a code such as
select type (element=>array(1))
class is (number)
! Code for any type and kind of Fortran number
That would be useful, but I don't see it happening soon.