- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi, I want to develope an interface that will make a callback from visual studio 2005 c++ to Fortran (CVF) dll function to echo the calcualtion progress.
Below are my testing codes:
Fortran DLL code:
! Cb1.f90
!
! FUNCTIONS/SUBROUTINES exported from Cb1.dll:
! Cb1 - subroutine
!
module GUI_OLI
implicit none
save
interface
integer function GUI_FCALL(PROG)
REAL*8 :: PROG
end function
end interface
pointer (p_GUI_FCALL, GUI_FCALL)
end module GUI_OLI
subroutine CONV ()
! Expose subroutine Cb1 to users of this DLL
!
!DEC$ ATTRIBUTES DLLEXPORT::CONV
USE GUI_OLI
IMPLICIT NONE
INTEGER i,j
REAL*8 m
IF(p_GUI_FCALL .ne. 0) THEN
DO i = 1, 100
m = i
j = GUI_FCALL(m)
END DO
END IF
end subroutine CONV
subroutine SETCALLBACKFUN (FCALL)
! Expose subroutine Cb1 to users of this DLL
!
!DEC$ ATTRIBUTES DLLEXPORT::SETCALLBACKFUN
USE GUI_OLI
IMPLICIT NONE
INTEGER(INT_PTR_KIND()) :: FCALL
p_GUI_FCALL = FCALL
end subroutine SETCALLBACKFUN
visual studio 2005 c++ code:
extern "C" {
void _stdcall SETCALLBACKFUN(void* progress);
void _stdcall CONV();
}
double g_dProgress;
void _stdcall Progress(double dPer)
{
g_dProgress = dPer;
return dPer;
}
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;
...
SETCALLBACKFUN(Progress);
CONV();
int j = 0;
...
return nRetCode;
}
When I debug to CONV() in c++ code. The visual studio crashs. I am not so familar with Fortran, can anyone help me find out what is the reason?
Thanks.
Regards
Chris
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Fortran passes arguments by reference; C passes them by value.
In your interface to GUI_FCALL, add
!dec$ attributes value :: prog
and see if that helps. That tells Fortran that the argument should be passed by value.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Chris,
I recently asked a similar question, although from C# rather than C++, in the forum: http://software.intel.com/en-us/forums/topic/391002.
Hopefully it is of some help to you,
Michael
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi, Lorri Menard, I make changes accordingly, but it still dosen't work.
Hi, Michael, It seems I cannot use PROCEDURE declare in my CVF code, and have to use Pointer instead. Do you have suggestions for using pointer instead. I guess the clash may be caused by the use of pointer for the callback fucntion,but don't know hoe to make it. Thanks.
Chris
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I no longer have a CVF installation available so I can't confirm this with CVF, but ... I used Intel Fortran and was finally able to create a runable program based on your code.
A couple of things to note: you've declared Progress as a "void", yet return a double (probably ignored by the C compiler), and then store it into a Fortran integer. I changed the return to an int.
If you really want to return a double, please check the CVF documentation on Mixed Language Programming to see if this return type requires a hidden argument. It most likely does not, but please check because if it does, you'll need to add that to your Progress routine.
And, if you do want to return a double, please make sure you declare the interface appropriately in the Fortran program too.
The final magic: also add a !dec$ attributes value :: fcall in SUBROUTINE SETCALLBACKFUN(FCALL)
Good luck!!
--Lorri
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi, Lorri,
It works now. Thanks a lot for your help. But I still have two problems. First,it works too slow. when i set the callback loop to 2 as
DO i = 1, 2
m = i
j = GUI_CALL(m)
END DO
it take more than half a minute to come back to C. Second, it cannot step into Progress function in C, and only updates the value of g_dProgrss to 2 after it come back to C. That is not I want. What I want is for each i value that puts in the callback, I can see the value of g_dProgrss is updated and in a faster way, in this way, I can update the progress bar accordingly. This can be achieved easily in the callback of C calling C or Fortran calling Fortran.
It is very appreciated If you can give some suggestions for it. Thanks.
Chris
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The code works fine. Thanks a lot for the help :-)
Chris

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page