Cross compiling problem of getarg

Cross compiling problem of getarg

15 posts / 0 nouveau(x)
Dernière contribution
Reportez-vous à notre Notice d'optimisation pour plus d'informations sur les choix et l'optimisation des performances dans les produits logiciels Intel.

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.

Steve

Could you drop the legacy hacks and use get_command_argument ?

removed

Citation :

TimP (Intel) a écrit :

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.

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.

Steve

Citation :

Steve Lionel (Intel) a écrit :

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.

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.

Citation :

TimP (Intel) a écrit :

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/70ed804d1752b201e3262bb8d1826a...

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. 

GET_COMMAND_ARGUMENT is not a macro, it's a standard intrinsic subroutine. It just happens to do the same thing as GETARG (at least the way we have implemented it), so we may have chosen to use the same library routine for it. I didn't mean that you should use GET_COMMAND_ARGUMENT in the C code, but rather in the Fortran code.

On Windows, you could just call the C getarg and iargc and stop messing with the Fortran internal library.

Steve

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.

You haven't hurt anyone but yourself. I am certainly not offended in any way - just trying to set you on the right path.

Steve

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:

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

c side:

extern void mygetarg(int*,char*,int*,int*);
int nlen, status;
 int ishift = i+1;
char name[256];
mygetarg(&ishift,name,&nlen, &status);

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?

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.

Steve

Thanks Steve! I'll add a 0 in the end of the string.

Connectez-vous pour laisser un commentaire.