472,357 Members | 1,937 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,357 software developers and data experts.

Passing address of a C++ function to Fortran - syntax??

I am trying to pass the address of a C++ function into a Fortran
routine to enable the Fortran routine to call this C++ function. I
have to do it this way as our build process does not allow circular
dependencies of DLL's.

Does anyone know how to do this, I have tried everything in my book.

I have a C++ function GetP:

DllExport void GetP()
{
...code...
return;
}

I am trying to pass the address of this function into a Fortran
routine called BIND_FTN. The call is made from another area of the
C++ code as follows:

void (GetP)();
DllImport void __stdcall BIND_FTN(int* GetP);

void Initialize()
{
...code...
BIND_FTN(GetP); // inform Fortran of address of callback
function
return;
}

The C++ will not compile, I get:
error C2664: 'BIND_FTN' : cannot convert parameter 1 from 'void
(__cdecl *)(void)' to 'int *'

Can anyone see the problem here?

Here is the Fortran code for BIND_FTN:

subroutine BIND_FTN_EXTERNALS[DLLEXPORT](ext)
external ext

interface
subroutine cb_GetP()
!DEC$ ATTRIBUTES STDCALL :: cb_GetP
end subroutine cb_GetP
end interface

pointer (p_GetP, cb_GetP)
p_GetP = loc(ext)

call cb_GetP ! call the C++ function from Fortran

return
end

(I haven't got to the Fortran yet - there may be syntax errors in
there)

Adrian
Jul 22 '05 #1
6 3413
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Adrian,

Adrian wrote:
I am trying to pass the address of a C++ function into a Fortran
routine to enable the Fortran routine to call this C++ function. I
have to do it this way as our build process does not allow circular
dependencies of DLL's.

Does anyone know how to do this, I have tried everything in my book.


Well, last time I did this with a C function calling a C++ library
function, I had to write a wrapper interface for the C++ which performed
any object initialization & type conversions. In addition to this
requirement, you also needed to mark the wrapper interface in an extern
"C"{} block in order that the linker be able to deal with the two
differing languages.

Evan
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFBo/s8pxCQXwV2bJARAt/2AJ9zSVfV4gc8dZH1zSayPa1zOwC4dgCfceHG
i9xCYAuLURLqt7Id4dVMrkM=
=Xiu3
-----END PGP SIGNATURE-----
Jul 22 '05 #2
Adrian wrote:
I am trying to pass the address of a C++ function into a Fortran
routine to enable the Fortran routine to call this C++ function. I
have to do it this way as our build process does not allow circular
dependencies of DLL's. Does anyone know how to do this, I have tried everything in my book.


I would first learn how to call C++ from Fortran, though I
believe that it is best to call C from Fortran and C++ from C.

If you can call C or C++ from Fortran then I wouldn't expect
passing the address to be too hard. I would look at the
calling convention for both, but C can pass function addresses,
and so can Fortran. There aren't so many ways to do it.

I do suggest a C intermediate, though.

-- glen

Jul 22 '05 #3
Adrian wrote:
| I am trying to pass the address of a C++ function into a Fortran
| routine to enable the Fortran routine to call this C++ function. I
| have to do it this way as our build process does not allow circular
| dependencies of DLL's.
|
| Does anyone know how to do this, I have tried everything in my book.
|
| I have a C++ function GetP:
|
| DllExport void GetP()
| {
| ...code...
| return;
| }
|
| I am trying to pass the address of this function into a Fortran
| routine called BIND_FTN. The call is made from another area of the
| C++ code as follows:
|
| void (GetP)();
| DllImport void __stdcall BIND_FTN(int* GetP);
|
| void Initialize()
| {
| ...code...
| BIND_FTN(GetP); // inform Fortran of address of callback
| function
| return;
| }
|
| The C++ will not compile, I get:
| error C2664: 'BIND_FTN' : cannot convert parameter 1 from 'void
| (__cdecl *)(void)' to 'int *'
|
| Can anyone see the problem here?

You're passing a function as the actual argument, but the declaration
says it should be an int*. Obviously, the declaration is wrong. You
need either void* and cast GetP in the call to void*, or, more nice,
spell it out:

typedef void __stdcall GETP(void);

DllImport void __stdcall BIND_FTN(GETP);

| Here is the Fortran code for BIND_FTN:
|
| subroutine BIND_FTN_EXTERNALS[DLLEXPORT](ext)
| external ext
|
| interface
| subroutine cb_GetP()
| !DEC$ ATTRIBUTES STDCALL :: cb_GetP
| end subroutine cb_GetP
| end interface
|
| pointer (p_GetP, cb_GetP)
| p_GetP = loc(ext)
|
| call cb_GetP ! call the C++ function from Fortran
|
| return
| end

No need to use Cray pointers here. Instead, just declare the argument
as external and spell out its interface:

subroutine BIND_FTN_EXTERNALS(cb_GetP)
!DEC$ATTRIBUTES DLLEXPORT:: BIND_FTN_EXTERNALS

interface
subroutine cb_GetP()
!DEC$ ATTRIBUTES STDCALL :: cb_GetP
end subroutine cb_GetP
end interface

call cb_GetP ! call the C++ function from Fortran

return
end

Here's the complete working C++ code:

#include "stdafx.h"
#include <stdio.h>

#define FORTRAN_DLL_CALL __stdcall

typedef void __stdcall GETP(void);
void __stdcall GetP(void);
extern "C" void FORTRAN_DLL_CALL BIND_FTN_EXTERNALS(GETP);

int main(int argc, char* argv[])
{
BIND_FTN_EXTERNALS(GetP); // inform Fortran of address of callback
return 0;
}

void __stdcall GetP(void)
{
printf("Hello World");
}
--
Jugoslav
___________
www.geocities.com/jdujic

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

Jul 22 '05 #4
Richard E Maine wrote:

(snip)
I do suggest a C intermediate, though.
Not that I've done scarecely any C++ interfacing myself, but my
understanding, from here and elsewhere, is that the biggest "trick" of
calling C++ from C is to make sure that the C++ routine is
defined with "extern C" (exact syntax might not be right, but
something like that). Once the C++ routine is callable from C, then it essentially is a
C routine, so no further intermediary is needed unless there are
independent reasons for one.


OK, I agree with this one. I thought it was calling an existing
C++ library (or DLL) function, but maybe not.

(snip)

-- glen

Jul 22 '05 #5
It sounds like you want to pass a function pointer from C/C++ to a Fortran
code. The Fortran code then calls the C/C++ function from a Fortran routine.

In general there are two things to consider. (1) naming conventions or
function decoration and (2) calling conventions. The function decoration is
highly dependent on the specific compilers that are being used. As far as
calling conventions are concerned the call into Fortran will require using
the standard call mechanism. The call from a Fortran External function will
use the C calling convention.

The function pointer can be passed as a void* from C/C++. If you want type
checking it can be defined differently.

I would be happy to help you with the details if you contact me at
Da***********@AdsorptionProcessModeling.com
"Adrian" <ac***@hotmail.com> wrote in message
news:6f**************************@posting.google.c om...
I am trying to pass the address of a C++ function into a Fortran
routine to enable the Fortran routine to call this C++ function. I
have to do it this way as our build process does not allow circular
dependencies of DLL's.

Does anyone know how to do this, I have tried everything in my book.

I have a C++ function GetP:

DllExport void GetP()
{
...code...
return;
}

I am trying to pass the address of this function into a Fortran
routine called BIND_FTN. The call is made from another area of the
C++ code as follows:

void (GetP)();
DllImport void __stdcall BIND_FTN(int* GetP);

void Initialize()
{
...code...
BIND_FTN(GetP); // inform Fortran of address of callback
function
return;
}

The C++ will not compile, I get:
error C2664: 'BIND_FTN' : cannot convert parameter 1 from 'void
(__cdecl *)(void)' to 'int *'

Can anyone see the problem here?

Here is the Fortran code for BIND_FTN:

subroutine BIND_FTN_EXTERNALS[DLLEXPORT](ext)
external ext

interface
subroutine cb_GetP()
!DEC$ ATTRIBUTES STDCALL :: cb_GetP
end subroutine cb_GetP
end interface

pointer (p_GetP, cb_GetP)
p_GetP = loc(ext)

call cb_GetP ! call the C++ function from Fortran

return
end

(I haven't got to the Fortran yet - there may be syntax errors in
there)

Adrian

Jul 22 '05 #6

"Jugoslav Dujic" <jd****@yahoo.com> wrote in message
news:30*************@uni-berlin.de...

[...]

You're undoubtedly aware that you can omit the DLLEXPORT metacommand in the
Fortran code and make the sample a straightforward mixed language one
instead of having to create a Fortran DLL.
--
Ciao,
Gerry T.
______
"Today's C++ programs will be tomorrow's unmaintainable legacy code." --Ian
Joyner, in a Critique of C++, 3rd ed., 1996.
Jul 22 '05 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
by: Wei-Chao Hsu | last post by:
Hi, I try to put an address of object into an int. Like this myclass obj; int address; address=&obj; "myclass" is an object of class or struct. It seems to illegal to C++. Is there any...
3
by: Pushkar Pradhan | last post by:
I need to pass the STL linked list to a function, this function should modify the linked list. So do I need to pass it by address, this is how I do it: void qhull(PARTICLE S, int len,...
58
by: jr | last post by:
Sorry for this very dumb question, but I've clearly got a long way to go! Can someone please help me pass an array into a function. Here's a starting point. void TheMainFunc() { // Body of...
1
by: Sam | last post by:
Hello all I have a two dimensional array (the dimensions are not known) that needs to be passed to fortran from c++, allocate the dimensions of the array in fortran code, do some filling up of...
6
by: dharmadam | last post by:
Is it possible to pass a column name or the order of the column name in the DB2 table table function. For example, I want to update the address of a person by passing one of the address column name...
23
by: David Frank | last post by:
How can I write a string function that encloses the input string in quotes "string" ?? below works for the "123 operation but adding " to it clobbers the "123 main() { char...
5
by: Adrian | last post by:
I am trying to pass the address of a C++ function into a Fortran routine to enable the Fortran routine to call this C++ function. I have to do it this way as our build process does not allow...
2
by: luis | last post by:
I'm using ctypes to call a fortran dll from python. I have no problems passing integer and double arryas, but I have an error with str arrys. For example: ..... StringVector = c_char_p *...
5
by: CapCity | last post by:
I'm sure I'm missing something simple - I do not code in C regularly, and the breaks are long enough for me to forget. The situation I have is I need to create an array but I do not know the...
2
by: Kemmylinns12 | last post by:
Blockchain technology has emerged as a transformative force in the business world, offering unprecedented opportunities for innovation and efficiency. While initially associated with cryptocurrencies...
1
by: Matthew3360 | last post by:
Hi there. I have been struggling to find out how to use a variable as my location in my header redirect function. Here is my code. header("Location:".$urlback); Is this the right layout the...
2
by: Matthew3360 | last post by:
Hi, I have a python app that i want to be able to get variables from a php page on my webserver. My python app is on my computer. How would I make it so the python app could use a http request to get...
0
by: AndyPSV | last post by:
HOW CAN I CREATE AN AI with an .executable file that would suck all files in the folder and on my computerHOW CAN I CREATE AN AI with an .executable file that would suck all files in the folder and...
0
by: Arjunsri | last post by:
I have a Redshift database that I need to use as an import data source. I have configured the DSN connection using the server, port, database, and credentials and received a successful connection...
0
Oralloy
by: Oralloy | last post by:
Hello Folks, I am trying to hook up a CPU which I designed using SystemC to I/O pins on an FPGA. My problem (spelled failure) is with the synthesis of my design into a bitstream, not the C++...
0
by: Carina712 | last post by:
Setting background colors for Excel documents can help to improve the visual appeal of the document and make it easier to read and understand. Background colors can be used to highlight important...
0
by: Rahul1995seven | last post by:
Introduction: In the realm of programming languages, Python has emerged as a powerhouse. With its simplicity, versatility, and robustness, Python has gained popularity among beginners and experts...
0
by: Ricardo de Mila | last post by:
Dear people, good afternoon... I have a form in msAccess with lots of controls and a specific routine must be triggered if the mouse_down event happens in any control. Than I need to discover what...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.