For Programmers: Free Programming Magazines  


Home > Archive > Fortran > December 2005 > Mystery with passing a function reference through the argument list.









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author Mystery with passing a function reference through the argument list.
R. MacDonald

2005-12-14, 9:59 pm

Hello, Group,

I have a new problem with which I am hoping for guidance.

Background:
I have a set of old and deeply nested largely independent Fortran
routines that used to be compiled into a rather large executable. I am
in the process of changing this so that it is structured as a number of
smaller DLLs, each of which can be invoked via a VB.Net application.

The old structure provided a few functions that were used to fetch and
put data to/from a common data structure. In the new structure, this
common data source is to be provided by the VB.net application. The
mechanism is that the VB.Net application passes the Fortran DLL a
reference to a call-back routine that can be invoked to provide the
required data. Thanks to previous assistance, I have this basic
mechanism working quite well.

Problem:
I would like to replace the current data functions with new functions
(of the same names) that call the VB.Net call-back to get/put the data.
The problem I have is that I can't seem to accomplish this without
passing the reference to the call-back function through the argument
list. This will then require that the majority of routines in the
Fortran application be modified so that they include the call-back
reference in the argument list. Besides being not very elegant, this
will be a lot of work.

Here is a synopsis that shows the problem I am having:

! This function is called by VB.Net
Integer Function TestFunction(DataCallBack, Message)
Use VBInterface
Integer DataCallBack ! "Pointer" to call-back function
Integer Message ! Pointer to message BStr.
Interface
. . .
iStatus = CBInit(DataCallBack)
. . .
End Function

Integer Function CBInit(DataCallBack)
Integer DataCallBack ! "Pointer" to call-back function
Integer iptSafeArray ! Pointer to SafeArray.

. . .
GlobalDataCB = DataCallBack
iStatus = ReadData('Read test', iptSafeArray)
. . .
End Function

where GlobalDataCB is a global integer variable declared in module
VBInterface. Then in the data handling functions:

Integer Function ReadData(Request, Result)
Use VBInterface
Character*(*), Intent(In) :: Request
Integer, Intent(InOut) :: Result ! Pointer to SafeArray.
. . .
iStatus = VBCallBack(GlobalDataCB, Request, Result)
. . .
End Function

Integer Function VBCallBack(ptrCallBack, Request, Result)
Character*(*), Intent(In) :: Request
Integer, Intent(InOut) :: Result ! Pointer to SafeArray.
Interface
Integer Function ptrCallBack(strRequest, intData)
Integer :: intData
Character*32 strRequest
End Function ptrCallBack
End Interface
. . .
! Get the requested data from the VB.Net application.
! (This call fails. VB reports a NullReferenceException.)
VBCallBack = ptrCallBack(Request, Result)
. . .
End Function

However, if I modify the argument list of ReadData to include the
original function reference passed to TestFunction, so it looks like this:

Integer Function ReadData(ptrCallBack, Request, Result)
Use VBInterface
Character*(*), Intent(In) :: Request
Integer, Intent(InOut) :: Result ! Pointer to SafeArray.
Interface
Integer Function ptrCallBack(strRequest, intData)
Integer :: intData
Character*32 strRequest
End Function ptrCallBack
End Interface
. . .
Call WriteLineX('aptrSSCallBack = ', aptrSSCallBack)
Call WriteLineX('ptrSSCallBack = ', ptrSSCallBack)

! This call to VBCallBack will succeed.
iStatus = VBCallBack(ptrCallBack, Request, Result)
! This call to VBCallBack will fail.
iStatus = VBCallBack(GlobalDataCB, Request, Result)
. . .
End Function

Then the first call to VBCallBack works, the second fails. I am calling
a subroutine to output the values of aptrSSCallBack and ptrSSCallBack to
a log file prior to making the calls to VBCallBack. (I can't write
these values directly because Fortran objects to writing out the value
of the function reference.) The values reported in the log file are
identical.

I guess that there is something going on behind the scenes here that I
don't understand. It seems that something different is being passed in
the first call than in the second -- perhaps some sort of hidden
argument. But I can't understand how this can be when both values
originate through the Integer argument passed via CBInit.

Can anyone help me understand what is going on here?
Can anyone suggest what I can do to pass this function reference via a
global rather than via an argument list?

Thanks in advance for any suggestions or insights that you can offer.

Cheers,
Randy
Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com