Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
Announcements
FPGA community forums and blogs on community.intel.com are migrating to the new Altera Community and are read-only. For urgent support needs during this transition, please visit the FPGA Design Resources page or contact an Altera Authorized Distributor.
29286 Discussions

Accessing C++ function pointer from Fortran

onkelhotte
New Contributor II
918 Views

Hi there,

I posted this on friday, but it was moved to the C++ Forum, but this is a Fortran specific question.

We want to get one of our projects to interact with Corba. A colleague created a C++ lib where he wrote some methods to connect to a name service daemon, start / stop a process and so on. He defined .idl files as well to handle the data exchange.

Now Ihaveto write an interface in fortran, so that a fortran program should be a server from which other clients get their data.

I got the fortran server connected to the name service and I can start and stop it from another process (in my case a C# GUI). But when it comes to the data exchange, the fortran server crashs.

My problem is (I think) the fortran interface of the routines that handle the data exchange. The following happens on the C++ side:

[bash]/*
SolverDataSingleValue handler functions
*/
extern "C" typedef int (*ccbl_set_single_value_handler)(double *val);
extern "C" typedef int (*ccbl_get_single_value_handler)(double *val);

/*
Registers a callback function which is invoked on set/get access of a
SolverDataSingleValue object with a specific key. NULL ptrs for handlers are permitted.
*/
extern "C" int ccbl_on_single_value(char *keyname,ccbl_set_single_value_handler hset,ccbl_get_single_value_handler hget);[/bash]

There are two function pointers, *ccbl_set_single_value_handler and *ccbl_get_single_value_handler. Now I have to write a fortraninterface for the method "ccbl_on_single_value". Those two handler types are type(c_funptr), arent they?

[bash]integer(C_INT) function ccbl_on_single_value(keyname, hset, hget) bind(C)
  use,intrinsic :: ISO_C_BINDING
  CHARACTER(KIND=C_CHAR),DIMENSION(*) :: keyname
  type(c_funptr) hset, hget
end function ccbl_on_single_value[/bash]

Then I wrote two functions that set / get a double value:

[bash]integer(C_INT) function set_single_value(val) bind(C)
  use,intrinsic :: ISO_C_BINDING
  use globMem
  real(C_DOUBLE) val
  print *, 'Set the test value'
  g_test_value = val
  set_single_value = 0
end function set_single_value

integer(C_INT) function get_single_value(val) bind(C)
  use,intrinsic :: ISO_C_BINDING
  use globMem
  real(C_DOUBLE) val
  print *, 'Get the test value'
  val = g_test_value
  get_single_value = 0
end function
[/bash]


g_test_value is defined in the module globMem. In the fortran main program I have an interface for those two functions, then I get the functions addresses and register "Testvalue" in the corba system:

[bash]set_test_value = c_funloc(set_single_value)
get_test_value = c_funloc(get_single_value)   
!   Register Handler   
i = ccbl_on_single_value('Testvalue'C, set_test_value, get_test_value) [/bash]

From my C# client I can see, that there is a "Testvalue" available. So this cant be all wrong :-)

set_test_value and get_test_value have an integer value that is the same as the hex value of set_single_value and get_single_value.

But when I want to set or get the value from the C# client,my fortran program crashes without a message. This happens too with a C++ client, which my colleague wrote to test his C++ server.

Im using VS2010 with the latest XE Update 8 compiler on Win7 64. The .lib was written with MS C++ from VS2010 and not with the Intel C++ compiler.

Ive found this thread, but it didnt helped me (http://software.intel.com/en-us/forums/showthread.php?t=70235&o=a&s=lr)

Thanks in advance,

Markus

0 Kudos
1 Solution
IanH
Honored Contributor III
918 Views
I think you just have an indirection issue, similar to what was discussed in the post you referenced.

The fortran interface block is for a function where two of the arguments are pointer-to-function (TYPE(C_FUNPTR)) passed by reference (reference being the "default" calling convention in Fortran-C interoperability in the absence of a specification to the contrary) - or if you like it is a pointer-to-pointer-to-function passed by value. The C declaration is for a function where two arguments are pointer-to-function passed by value - one level of indirection short of your Fortran declaration.

Try adding the VALUE attribute to the declaration of the function pointer dummy arguments in the Fortran interface block, ie.

type(c_funptr), VALUE :: hset, hget

View solution in original post

0 Kudos
2 Replies
IanH
Honored Contributor III
919 Views
I think you just have an indirection issue, similar to what was discussed in the post you referenced.

The fortran interface block is for a function where two of the arguments are pointer-to-function (TYPE(C_FUNPTR)) passed by reference (reference being the "default" calling convention in Fortran-C interoperability in the absence of a specification to the contrary) - or if you like it is a pointer-to-pointer-to-function passed by value. The C declaration is for a function where two arguments are pointer-to-function passed by value - one level of indirection short of your Fortran declaration.

Try adding the VALUE attribute to the declaration of the function pointer dummy arguments in the Fortran interface block, ie.

type(c_funptr), VALUE :: hset, hget
0 Kudos
IDZ_A_Intel
Employee
918 Views
Shame on me... Of course it has to be value.

Now it works, thanks a lot!

Markus
0 Kudos
Reply