Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
29386 Discussions

Function that returns a derived type...

mountain_ike
Beginner
2,479 Views

I was wondering if there is anyway that a fortran function can be used to return a derived type.  I am building a fortran function (compiled into a DLL) that will be called by a JAVA program.  This generally works well, and returning regular variables (integers, reals, etc) is really very simple.  However, it would be nice to be able to return a 'class' in the form of a derived type.  There is a way to map classes to derived types as passed arguments, but I have not been able to find a way to make it work with a return from a function call.

0 Kudos
6 Replies
Steven_L_Intel1
Employee
2,479 Views

Yes, certainly. There isn't anything special about this. You don't even need an explicit interface for a function returning a non-polymorphic derived type. For example:

function dtype (arg) bind(C)
type, bind(C) :: dtype_t
  integer i
end type dtype_t
type(dtype_t) :: dtype
integer :: arg
dtype%i = arg
return
end

program test
type, bind(C) :: dtype_t
  integer i
end type dtype_t
interface
  function dtype (arg) bind(C)
  import
  type(dtype_t) :: dtype
  integer :: arg
  end function dtype
end interface

type(dtype_t) :: local

local = dtype(3)
print *, local%i
end

Some comments about this example. First, I didn't need to use an explicit interface, I could have just said:

type(dtype_t) :: dtype

but I consider that bad form. Second, normally I would have put the function and the type in a module, but you say you are calling Java so the actual function would not be Fortran. Third, I added BIND(C) to indicate C-compatible calling and function returns. I am not sure what your Java wants here.

I will comment that you need to make sure Java is returning the derived type in the same manner Fortran expects it. Without BIND(C), Fortran will pass a hidden first argument where the function value should be returned. With BIND(C), it won't do that for "small" return values, typically 8 bytes or less.

0 Kudos
mountain_ike
Beginner
2,479 Views

Steve,

     You are always to go-to guy!  This worked great in Fortran (although I needed to put the type declaration into a module).  Now the challenge will be to get JAVA to like it...

0 Kudos
mountain_ike
Beginner
2,479 Views

Having a derived type as a passed argument works fine.  The values get passed from JAVA into fortran with no problem.  However, using this implementation for returning a derived type from a function call is not so clean.  The passed arguments get garbled when they reach the fortran function, and the function crashes when it tries to write to the derived type variables (even with the bind(C) command).  This may be a new thread, and possibly not one for the fortran board...

0 Kudos
Steven_L_Intel1
Employee
2,479 Views

Maybe you need to write the Java function as one where the result is explicitly passed as an argument (making it into a subroutine). It could be that Java can't handle structure function results in a way compatible with Fortran.

0 Kudos
mountain_ike
Beginner
2,479 Views

I'll look into it.  My application will require that the returns all be from the method, but maybe I can encapsulate the results internally before sending them out.  I've done that in C#...I was just hoping for an easy short cut!

0 Kudos
Steven_L_Intel1
Employee
2,479 Views

Is it possible that Java is assuming STDCALL when you call it? This would corrupt the stack on return if there is a mismatch.

0 Kudos
Reply