473,609 Members | 2,187 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

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_EXTERN ALS[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 3521
-----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/s8pxCQXwV2bJARA t/2AJ9zSVfV4gc8dZ H1zSayPa1zOwC4d gCfceHG
i9xCYAuLURLqt7I d4dVMrkM=
=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_EXTERN ALS[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_EXTERN ALS(cb_GetP)
!DEC$ATTRIBUTES DLLEXPORT:: BIND_FTN_EXTERN ALS

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_CAL L __stdcall

typedef void __stdcall GETP(void);
void __stdcall GetP(void);
extern "C" void FORTRAN_DLL_CAL L BIND_FTN_EXTERN ALS(GETP);

int main(int argc, char* argv[])
{
BIND_FTN_EXTERN ALS(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***********@A dsorptionProces sModeling.com
"Adrian" <ac***@hotmail. com> wrote in message
news:6f******** *************** ***@posting.goo gle.com...
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_EXTERN ALS[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.c om> 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
7086
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 way to do this task?
3
2860
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, list<PARTICLE> &hull, list<PARTICLE>::iterator &iter1, list<PARTICLE>::iterator &iter2, PARTICLE a, PARTICLE b, int rank, int numtasks) I think that's working but I have another problem: I need to pass two
58
10107
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 code... TCHAR myArray; DoStuff(myArray);
1
6415
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 the array in fortran and then accessing it in my c++ code. Say in my c++ code I have; extern "C" { void foo_(float **, int &, int &); }
6
6288
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 like ZIP CODE or ADDRESS LINE. I will call the function with three parameter--UpdateAddress(5,zip_code,person_id) where 5 indicates ZIP_CODE is the fifth column in the table. If 4 is passed, it indicates the address line is to be updated. ...
23
4008
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 *sfun(char *); printf("%s",sfun("123"));
5
2331
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 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()
2
4428
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 * len(id) # id is a list of strings Id_dat=StringVector() for i in range(len(Id)): ....Id_dat=id
5
1469
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 dimension until runtime. I pass the pointer to a function which then determines the size and then creates and populates it. I can walk the array OK in the function, but the app crashes when I try to do so in the calling routine. Here's a small...
0
8534
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, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
8509
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 tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
8188
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 Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
8374
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
6969
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, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
5502
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4002
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
1630
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
1366
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.