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.

callback function

weichao
Beginner
720 Views
Hi,

I want to simulate the callback mechanism with C and FORTRAN. The projects can be built successfully. But it still have a problem. The function event should print something but it doesn't. I am not a C expert. Anyone could help me?

In FORTRAN part:

module mymod
implicit none

interface
subroutine do_it(str,callback)
!dec$ attributes c :: do_it
!dec$ attributes reference :: str
implicit none
character(*)::str
external callback
end subroutine do_it
end interface

end module mymod

!_______________________
program test
use mymod
implicit none
character(40)::str
external event
str="Event is raised."
call do_it(str,event)
end program

!________________________
subroutine event(str)
implicit none
character(*)::str

print*,str

end subroutine event
!________________________

In C part:

typedef void (*CALLBACKPROC)(char* str);
extern "C"
{
void do_it(char* str,CALLBACKPROC callback)
{
callback(str);
}
}
0 Kudos
4 Replies
Steven_L_Intel1
Employee
720 Views
I can't find CALLBACKPROC defined anywhere in the MSVC headers or documentation. But in Windows programming, callback procedures are usually STDCALL...

Steve
0 Kudos
Jugoslav_Dujic
Valued Contributor II
720 Views
Steve, there's typedef for CALLBACKPROC in the code ;-)

The problem is that it's wrong. You need instead (d'oh, I hate that syntax, I have to look back in the sample every time):
typedef void (__stdcall *CALLBACKPROC)(char*, int)
i.e. it must match the prototype of Fortran routine Event. Passing characters between C and Fortran is a bit tricky as there's hidden argument describing length. There are many ways to solve it, depending on what you need with the argument (only reading, reading/writing, writing). One solution can be to terminate it with �:

str="Event is raised."//char(0)
call do_it(str, event)
...
void do_it(char* str, CALLBACKPROC callback)
{callback(str, strlen(str)); }
Jugoslav

0 Kudos
weichao
Beginner
720 Views
Thank you,Jugoslav. It works but I don't use __stdcall.
0 Kudos
Jugoslav_Dujic
Valued Contributor II
720 Views
__stdcall is the default convention for all CVF routines. You can change it in project settings though -- did you do that? (Project/Settings/Fortran/External procedures/Argument passing convention). If you didn't, you'd better either use __stdcall or change the setting above to "C, by reference", or you'll get a smashed stack.

Jugoslav
0 Kudos
Reply