- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Why are you calling the Fortran internal run-time library routines from C? That's not supported.
I think your prototype of for_getarg is wrong. I'd expect there to be four arguments to it (the character argument takes an address and length, and you need to supply a NULL for the status argument if not using it. Why you use "short" I also don't understand.
If you want the Fortran functionality, write a Fortran routine that calls getarg and call that - or use GET_COMMAND_ARGUMENT.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Could you drop the legacy hacks and use get_command_argument ?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
removed
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
TimP (Intel) wrote:
Could you drop the legacy hacks and use get_command_argument ?
Hi TimP. I am compiling a library and there is a same error. That's not my idea.
Trust me. I'd use getarg/get_command_argument, not the functions in my post for my own code.
Sorry for the confuse.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
That's the correct page for the GETARG intrinsic. But the internal routine it calls will actually have four arguments - the argument number, address of character string, address of status argument (or 0 if omitted), and a "size_t" integer for the length of the character argument, passed by value. You are passing the wrong datatypes and passing the length by reference rather than value. You're lucky you got an access violation given how wrong this code is.
Rather than trying to patch it over, please do it right.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Steve Lionel (Intel) wrote:
That's the correct page for the GETARG intrinsic. But the internal routine it calls will actually have four arguments - the argument number, address of character string, address of status argument (or 0 if omitted), and a "size_t" integer for the length of the character argument, passed by value. You are passing the wrong datatypes and passing the length by reference rather than value. You're lucky you got an access violation given how wrong this code is.
Rather than trying to patch it over, please do it right.
Thanks Steve. Now I get it.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
In line with what Steve said, internal implementations of the legacy getarg function will differ among various Fortran implementations; besides, a web search shows open source implementations with little documentation which may have been copied from libf2c (an early implementation of F77 runtime). Although that was last used with g77, normal usage would not have involved calling the internal C implementation directly, even when using Fortran compilation based on f2c. So, using poorly conceived open source which depends on a particular seldom used interface has limitations. libf2c functions will conflict with the run-time libraries of current Fortran compilers.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
TimP (Intel) wrote:
In line with what Steve said, internal implementations of the legacy getarg function will differ among various Fortran implementations; besides, a web search shows open source implementations with little documentation which may have been copied from libf2c (an early implementation of F77 runtime). Although that was last used with g77, normal usage would not have involved calling the internal C implementation directly, even when using Fortran compilation based on f2c. So, using poorly conceived open source which depends on a particular seldom used interface has limitations. libf2c functions will conflict with the run-time libraries of current Fortran compilers.
Thanks TimP. I don't know much about libf2c. I am not sure whether the code that I am compiling has any relationship to libf2c. But thanks for telling me the knowledge. Here is the link for the code (maybe you want to take a look): https://bitbucket.org/petsc/petsc-3.3/src/70ed804d1752b201e3262bb8d1826a110fee28fe/src/sys/ftn-custom/zstart.c
You are right. I am compiling it for personal use currently. I am not a pro like you, so I just want to have it compiled...
The error goes away when I use for_getcmd_arg with four prameters (that I followed Steve's suggestion) instead of for_getarg with three prameters. But I still don't understand how things work. So far it seems that GET_COMMAND_ARGUMENT works like a macro. And will be replaced by for_getarg when there are 3 prameters, by for_getcmd_arg when 4. I don't see why for_getcmd_arg gives no error message but for_getarg does. If you use GET_COMMAND_ARGUMENT in the c code (getarg.c), it will fail when linking.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Sorry for messing the Fortran internal library. It seems my post makes intel developer feel bad. And I did something improper. I shall remove all of my posts. I wanted to know how, not to hurt you.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Steve and Timp,
I read a lot last week. Now I understand you better. Sorry for the misunderstood 2 weeks ago. I didn't have enough knowledge that day when I discuss this problem. So this time, would you please take a look at my code? Hope I did it OK this time. I appreciate your patient and time.
Fortran side:
[fortran]
subroutine getstring(number, name, nlen, status) bind(C,name='mygetarg')
use, intrinsic :: iso_c_binding
implicit none
integer(kind=c_int), intent(IN) :: number
character(kind=c_char), dimension(256), intent(INOUT) :: name
integer(kind=c_int), intent(INOUT) :: nlen
integer(kind=c_int), intent(INOUT) :: status
character(len=256) :: name_tmp
call get_command_argument(number, name_tmp, nlen, status)
name=transfer(name_tmp, name)
end subroutine getstring
[/fortran]
c side:
[cpp]
extern void mygetarg(int*,char*,int*,int*);
int nlen, status;
int ishift = i+1;
char name[256];
mygetarg(&ishift,name,&nlen, &status);
[/cpp]
fortran code compiled with /iface:cref.
Here I am not sure about the "Character-length argument passing". Does it mean I have to write subroutine with four arguments in fortran, and extern void mygetarg with 5 arguments in c to make it right? What will happen if they don't match?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
This code is almost right., First, you don't need /iface here. Second, when you use BIND(C), there are no hidden arguments, so you have declared it right. The only thing I see as a problem is that get_command_argument will not put a NUL at the end of the string, which the C code will want. Since you're getting the length back in nlen, you can use that.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks Steve! I'll add a 0 in the end of the string.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page