473,408 Members | 1,734 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,408 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 3503
-----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...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

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.