- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Ok, I'm stumped here.
I've got a bunch of legacy code from a HP-UX project to port and I think I've done everything right, yet when I run the code any C routine that calls Fortran seems to break at the end of the routine. That is, I get an error 'User breakpoint called at memory location' and the debugger shows me the closing brace of a C routine.
If I replace the Fortran called function within the C function with a C version (some of these routines are simple and its easy to test this) then the original C function works just fine and I get the same User breakpoint error at the next C routine that calls Fortran.
I've found a page in the VF help which makes me think I've done something wrong, but I'm a bit lost what it is. The page is entitled "Stack Considerations in Calling Conventions." I think everything is going wrong because of the variable length [not sure if its the right term, the "REAL*8 crv(24,0:*)" type declaration] variables the Fortran is using.
I've compiled the Fortran as-is, that is there isn't any Windows specific code within the Fortran to deal with the Visual Studio needs for mixed language programming. I've changed the character string length passing to be at the end of all arguments to match the behaviour I was seeing on HP-UX, the source of all this code. I've also defined implicit INT's as 4 byte and REALs as 8-byte, again to match what we used on HP-UX.
Here's the specifics that I think are applicable:
Fortran routine:
SUBROUTINE GARCCRV(IGIVEN,ARC,CRV)
IMPLICIT REAL*8(A-H,O-Z)
dimension arc(16),crv(24,0:*)
...
C invoking call:
void make_c_nurb( const Point edge0,
const Point edge1,
const Point center0,
const Point center1,
double center_nurb_data[][ 24 ],
double c_nurb_data[][ 24 ] )
...
int j;
double arc[16];
...
FTN( garccrv ) (&j, arc, mn_cc_crv);
Some defines I've made:
#define FTN(name) name##_
#define garccrv_( a, b, c ) GARCCRV( a, b, c )
I've got a bunch of legacy code from a HP-UX project to port and I think I've done everything right, yet when I run the code any C routine that calls Fortran seems to break at the end of the routine. That is, I get an error 'User breakpoint called at memory location' and the debugger shows me the closing brace of a C routine.
If I replace the Fortran called function within the C function with a C version (some of these routines are simple and its easy to test this) then the original C function works just fine and I get the same User breakpoint error at the next C routine that calls Fortran.
I've found a page in the VF help which makes me think I've done something wrong, but I'm a bit lost what it is. The page is entitled "Stack Considerations in Calling Conventions." I think everything is going wrong because of the variable length [not sure if its the right term, the "REAL*8 crv(24,0:*)" type declaration] variables the Fortran is using.
I've compiled the Fortran as-is, that is there isn't any Windows specific code within the Fortran to deal with the Visual Studio needs for mixed language programming. I've changed the character string length passing to be at the end of all arguments to match the behaviour I was seeing on HP-UX, the source of all this code. I've also defined implicit INT's as 4 byte and REALs as 8-byte, again to match what we used on HP-UX.
Here's the specifics that I think are applicable:
Fortran routine:
SUBROUTINE GARCCRV(IGIVEN,ARC,CRV)
IMPLICIT REAL*8(A-H,O-Z)
dimension arc(16),crv(24,0:*)
...
C invoking call:
void make_c_nurb( const Point edge0,
const Point edge1,
const Point center0,
const Point center1,
double center_nurb_data[][ 24 ],
double c_nurb_data[][ 24 ] )
...
int j;
double arc[16];
...
FTN( garccrv ) (&j, arc, mn_cc_crv);
Some defines I've made:
#define FTN(name) name##_
#define garccrv_( a, b, c ) GARCCRV( a, b, c )
Link Copied
5 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Did you also change the argument passing mechanism for Fortran to be "C, by reference"? You'll need that.
Steve
Steve
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Changing the argument passing mechanism is an interesting idea, but now I get tons of unresolved symbol messages:
error LNK2001: unresolved external symbol _USER_MESSAGEF
I had previously stuck in things like this in my 'C' code to make it 'callable' from Fortran:
void __stdcall USER_MESSAGEF( arg list )
{
user_messagef( same args );
}
void user_messagef( arg list )
{
...
So, do I want to just remove the __stdcall macro here, yet still define a 'Fortran' named version of my function?
error LNK2001: unresolved external symbol _USER_MESSAGEF
I had previously stuck in things like this in my 'C' code to make it 'callable' from Fortran:
void __stdcall USER_MESSAGEF( arg list )
{
user_messagef( same args );
}
void user_messagef( arg list )
{
...
So, do I want to just remove the __stdcall macro here, yet still define a 'Fortran' named version of my function?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hmm, doesn't seem like I can edit messages I've posted here....
Also, the idea of changing the Fortran compilation will only work where I have the source, what about calling a Fortran function that's in a 'precompiled' library, where I won't be able to recompile it.
Perhaps there's some way within the C calling function to fix things?
Also, the idea of changing the Fortran compilation will only work where I have the source, what about calling a Fortran function that's in a 'precompiled' library, where I won't be able to recompile it.
Perhaps there's some way within the C calling function to fix things?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I thought you didn't want to change the source. Ok, add the __stdcall to the declaration of the Fortran routine you call from C.
Steve
Steve
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I admit I got lost who calls whom and which source needs adjustment... to avoid further confusion, I suggest you add somewhere in you C header something like
#define FORTRAN_CALL __stdcall
or
#define FORTRAN_CALL __cdecl
(whatever is appropriate to compiler switch you use to compile Fortran) and declare all Fortran routine declarations and C routines called from Fortran as FORTRAN_CALL.
Jugoslav
#define FORTRAN_CALL __stdcall
or
#define FORTRAN_CALL __cdecl
(whatever is appropriate to compiler switch you use to compile Fortran) and declare all Fortran routine declarations and C routines called from Fortran as FORTRAN_CALL.
Jugoslav
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page