Function pointer as function parameter 
Author Message
 Function pointer as function parameter

I've developed an application using both fortran and C languages.

Fortran layer is the upper layer and uses C functions to perform low
level operations.
I need to supply a Fortran function to a C function as parameter (C
function has a pointer to function as parameter) in order to let the C
function call the Fortran one.

It creates me some problems... function pointer is not correctly
passed to C function...

Can someone give me some advice to solve this problem ???

// This is the fortran call where createthread is the C function and
proc_x_dsv2 is the fortran function supplied as parameter

l_iThreadId = createthread(proc_x_dsv2)

// This is the C function that have to manage the supplied fortran
function...

int createthread_(void* p_pThreadFunction(void*))
{
   int         l_iResult;
   pthread_t   l_ThreadID;

  if(pthread_setconcurrency(1) != 0)
   {
      return -1;
   }  

     /* create the new thread (exit on failuree) */

      printf("arrivato alla chiamata \n");
      if (pthread_create(&l_ThreadID, NULL, (void*(*)(void *))
p_pThreadFunction,  NULL) > 0)
      {
         pthread_kill(l_ThreadID, SIGKILL);
         return -1;
      }

   return (int)l_ThreadID;

Quote:
}



Sun, 08 Oct 2006 17:20:29 GMT  
 Function pointer as function parameter
| I've developed an application using both Fortran and C languages.
|
| Fortran layer is the upper layer and uses C functions to perform low
| level operations.
| I need to supply a Fortran function to a C function as parameter (C
| function has a pointer to function as parameter) in order to let the C
| function call the Fortran one.
|
| It creates me some problems... function pointer is not correctly
| passed to C function...
|
| Can someone give me some advice to solve this problem ???
|
| // This is the fortran call where createthread is the C function and
| proc_x_dsv2 is the fortran function supplied as parameter
|
| l_iThreadId = createthread(proc_x_dsv2)

| int createthread_(void* p_pThreadFunction(void*))
|       if (pthread_create(&l_ThreadID, NULL, (void*(*)(void *))
| p_pThreadFunction,  NULL) > 0)

what the heck is this (void*(*)(void *)) cast? I'm lost. What happens
if you remove that superfluous cast?

--
 Jugoslav
___________
www.geocities.com/jdujic

Please reply to the newsgroup.
You can find my real e-mail on my home page above.



Sun, 08 Oct 2006 18:08:33 GMT  
 Function pointer as function parameter

Quote:

> I've developed an application using both Fortran and C languages.

> Fortran layer is the upper layer and uses C functions to perform low
> level operations.
> I need to supply a Fortran function to a C function as parameter (C
> function has a pointer to function as parameter) in order to let the C
> function call the Fortran one.

> It creates me some problems... function pointer is not correctly
> passed to C function...

> Can someone give me some advice to solve this problem ???

The easiest way to solve this conundrum is this:

1. Say you want to use Fortran subroutines SUBA, SUBB and SUBC
   each in a separate thread.

2. Create C functions csuba, csubb, csubc that each do no
   more than call the corresponding Fortran routines.

3. Pass these C functions to the pthread_create() function.

It may not be an elegant solution, but its saves you the
trouble of trying to figure out the correct cast for the
pointer to a Fortran routine ...

Regards,

Arjen



Sun, 08 Oct 2006 19:29:17 GMT  
 Function pointer as function parameter
"> what the heck is this (void*(*)(void *)) cast? I'm lost. What happens

Quote:
> if you remove that superfluous cast?

Without this cast... C functions doesn't compile !!!!!!


Sun, 08 Oct 2006 21:45:28 GMT  
 Function pointer as function parameter

Quote:

> I've developed an application using both Fortran and C languages.
> Fortran layer is the upper layer and uses C functions to perform low
> level operations.
> I need to supply a Fortran function to a C function as parameter (C
> function has a pointer to function as parameter) in order to let the C
> function call the Fortran one.
> It creates me some problems... function pointer is not correctly
> passed to C function...
> Can someone give me some advice to solve this problem ???

(snip)

Quote:
> int createthread_(void* p_pThreadFunction(void*))

(snip)

Quote:
>       if (pthread_create(&l_ThreadID, NULL, (void*(*)(void *))
> p_pThreadFunction,  NULL) > 0)

What I usually do at this point, if it isn't explained exactly
in the manuals, is to compile both, or the smallest program that
can demonstrate function pointer calling, with the option
(usually -S for C compilers) to print out the generated code and
see how it is being passed.

As with the other reply, I am suspicious of the cast.

The only other one I can think of is that Fortran could pass
a pointer to the function pointer.

-- glen



Sun, 08 Oct 2006 22:13:54 GMT  
 Function pointer as function parameter
| "> what the heck is this (void*(*)(void *)) cast? I'm lost. What happens
|| if you remove that superfluous cast?
|
| Without this cast... C functions doesn't compile !!!!!!

FWIW, my MS VC++ does not complain without it:

==============================================================
int pthread_create(void *(*start_routine)(void*));

int pthread(void *p_pThreadFunction(void*))
{
   pthread_create(p_pThreadFunction);
   pthread_create((void*(*)(void *))p_pThreadFunction);

Quote:
}

==============================================================

(I abbreviated pthread_create just to the parameter in question).
I don't see why the cast is necessary (and I admit my mind gets
a buffer overflow trying to find out what it means).

However, the end result appears to be the same, so this doesn't
seem to be the root of the problem. As Glen pointed out, could you
post a minimal sample that demonstrates the problem? How did
you conclude that "function pointer is not correctly
passed to C function..." -- that means you'd almost certainly get
a SIGSEGV?

Did you declare that proc_x_dsv2 is at least an EXTERNAL in the
routine which calls createthread (if not providing an INTERFACE/
module association).

--
 Jugoslav
___________
www.geocities.com/jdujic

Please reply to the newsgroup.
You can find my real e-mail on my home page above.



Sun, 08 Oct 2006 22:41:15 GMT  
 Function pointer as function parameter


Quote:
> I've developed an application using both Fortran and C languages.

> Fortran layer is the upper layer and uses C functions to perform low
> level operations.
> I need to supply a Fortran function to a C function as parameter (C
> function has a pointer to function as parameter) in order to let the C
> function call the Fortran one.

> It creates me some problems... function pointer is not correctly
> passed to C function...

> Can someone give me some advice to solve this problem ???

> // This is the fortran call where createthread is the C function and
> proc_x_dsv2 is the fortran function supplied as parameter

> l_iThreadId = createthread(proc_x_dsv2)

> // This is the C function that have to manage the supplied fortran
> function...

> int createthread_(void* p_pThreadFunction(void*))

Until/unless you get F2003 with C interoperability, Fortran does not
have any notion of a function returning a C-type pointer (address
only); you can in F9x have a POINTER FUNCTION, but that's a F9x (fat,
even obese) pointer, very different from a C one. To use a Fortran
function directly, you will need it to return a type which can
actually be treated as void*.  On practically all systems nowadays,
all data (at least) pointers are really just numeric addresses and
some kind of integer will do this; on a lot of systems default INTEGER
will, but nothing requires or guarantees that. However, you may have
trouble on AS/400 -- if there even is a Fortran on it.

Technically again Fortran has no concept of void* arguments, but in
practice all data pointers are the same, and although not formally
guaranteed at least array arguments, and all pre-F9x (implicit)
arguments, will almost always be passed as C-like pointers, except for
CHARACTER which will usually be passed as C-like pointer plus length
which you definitely don't want.

As already suggested, if you can't make the Fortran interface right
you can always write a little C wrapper for it. In fact, since you
currently aren't using the thread_routine argument for anything, on
systems where a function pointer can losslessly be converted to void*
which is effectively required by POSIX anyway (for dlsym) though not
by C, you could write a single generic C wrapper that gets passed the
pointer to the Fortran procedure with whatever (fixed, or determinable
by some other means) signature you want. (Except, probably, a Fortran
internal procedure; I think those usually require a special calling
convention, that is at best very difficult to mimic from C.)

Quote:
> {
>    int         l_iResult;
>    pthread_t   l_ThreadID;

>   if(pthread_setconcurrency(1) != 0)
>    {
>       return -1;
>    }  

>      /* create the new thread (exit on failuree) */

>       printf("arrivato alla chiamata \n");

On some systems, if your main program is not C, using certain parts of
the C library, >especially< I/O, won't work. (And if your main program
is not Fortran, similarly some Fortran features won't work.)

Quote:
>       if (pthread_create(&l_ThreadID, NULL, (void*(*)(void *))
> p_pThreadFunction,  NULL) > 0)
>       {
>          pthread_kill(l_ThreadID, SIGKILL);
>          return -1;

If this delivers a signal at all -- and I'm not sure it will, because
the threadID is not valid if pthread_create failed -- it kills the
whole process rather than exiting as your comment says and would
probably be better as it allows cleanup to occur. SIGKILL is one of
several signals whose *effect* is always process wide no matter to
which thread it is delivered, and one of two that cannot be handled.

Quote:
>       }

>    return (int)l_ThreadID;

Pthreads doesn't require that a thread_id can be cast to int, or
indeed at all, or that the result is of any use if they are; and
according to the more experienced folks on comp.programming.threads
there are real systems where it can't or isn't. But presumably you're
OK on the system you're on; if you care about portability see c.p.t.

Quote:
> }

- David.Thompson1 at worldnet.att.net


Fri, 13 Oct 2006 11:07:24 GMT  
 Function pointer as function parameter
Quote:
> int createthread_(void* p_pThreadFunction(void*))

I am not sure what exactly you are trying to do, but
isn't it supposed to be
int createthread_(void* (*p_pThreadFunction)(void*))
{
...
Quote:
}

and get rid of the cast?
I have been passing c functions to Fortran without any
problems.


Sun, 15 Oct 2006 07:10:56 GMT  
 Function pointer as function parameter

Quote:
> > int createthread_(void* p_pThreadFunction(void*))
> I am not sure what exactly you are trying to do, but
> isn't it supposed to be
> int createthread_(void* (*p_pThreadFunction)(void*))

Not as far as any standard-conforming compiler is concerned.

In C if you write a declaration of a function parameter=dummy=formal
as a function, it actually declares a pointer to function (with that
type=signature) and similarly when you write a function name (not
&funcname) as an argument=actual in a call, or indeed in any
expression, it "decays" (is automatically converted) to a pointer, so
you so can do for example:
void alpha (int, double);
void beta (int, double);
void myfuncptrs[2] (int,double) = { /* & optional */ alpha, beta };

Nearly all compiled languages I know of, even those stricter about
types than C, do something of this sort, because routines (by whatever
term) aren't data values and can't be passed; e.g. in Pascal, you can
(explicitly) declare formals to be by reference (VAR) or by value, but
you declare subprogram formals with a different syntax which
effectively is always by reference.

This is similar to the much more commonly encountered -- and arguably
more surprising -- feature of C that arrays are not first class; if
you declare a function parameter as an array of T it is actually a
pointer to T (the element type), and when you write an array in a call
or expression (with minor exceptions) it decays to a pointer to the
first element.

Some people prefer to actually write the C declarations as pointer to
function, and pointer to (array) element, to be clear to others and/or
remind themselves what is going in, but this isn't required.

- David.Thompson1 at worldnet.att.net



Fri, 20 Oct 2006 16:41:20 GMT  
 
 [ 9 post ] 

 Relevant Pages 

1. Function parameter names within a function

2. tcl+C function with pointer function argument?

3. Returning Pointer To Pointer From Function

4. VC++ calling fortran function and fortran function calling a c++ function

5. Calling functions from functions from functions ...

6. optional and variant parameters in COM functions

7. return more than one parameter from a function

8. Problem of passing string parameter in DLL's function from a C application

9. Function Parameters IT WORKS

10. Parameter List for a C function

11. mentioning unused parameters in function calls

12. Function returning TWO parameters

 

 
Powered by phpBB® Forum Software