- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I had read a topic of calling C++ from FORTRAN.
Basically, I need to access C++ class data from FORTRAN- when calling C++ from FORTRAN.
Steve suggested in one of his post to use access routines (get, put, etc.) if you need to communicate class data between the languages (
http://software.intel.com/en-us/forums/topic/296424)
.
Please can anyone advise what exactly you eman by access routines?
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I had read a topic of calling C++ from FORTRAN.
Basically, I need to access C++ class data from FORTRAN- when calling C++ from FORTRAN.
Steve suggested in one of his post to use access routines (get, put, etc.) if you need to communicate class data between the languages (
http://software.intel.com/en-us/forums/topic/296424)
.
Please can anyone advise what exactly you eman by access routines?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
What I mean is: instead of trying to read and write the C++ variables directly from Fortran, write functions in C++ that return the value of a specific variable and, if necessary, functions to set the value of a variable. You can call these from Fortran and it spares you a lot of C+++ messiness.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks Steve-However, I'm not evr clear.
1) I have a FORTRAN routine MyFORTRANRoutine()
2) I have a cpp routine MYCPPRoutine_A which is a member of a class (sat MyClass_A). So, I cannot call it from FORTRAN (Right?- or let us say it is not easyto do that)
3) You say write functions in C++ that return the values of specific variable. I did not get that. Should these functions be public members of class MyClass_A ?
Can you jsut put it in form of step 1, step 2, step 3- what exactly you meant?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
No, I can't really put it that way. You need to write 'extern "C"' routines in your C++ source that are callable from Fortran. These routines would then get or set the variables. They would not be members of classes, but separate routines. I am not a C++ expert so I don't know all the details.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Sandeep: You can, conceptually at least, do what Steve suggested in two steps:
1. Write code in C (not C++) to access the C++ object components. Make sure that the components are the usual built-in C types for which Fortran has equivalents. Test the code out and confirm that it works.
2. Convert the access functions that you wrote in Step 1 to Fortran, either using C-interoperability features or using older mixed-language programming techniques.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I was not suggesting step 2 - indeed one may not be able to do that. What I had in mind was writing C++ routines that accessed the class, but was coded as an 'extern "C"' routine so that it had C calling compatibility, that took arguments or returned values interoperable with Fortran. These routines could then easily be called from the Fortran code using the C interoperability features.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Did you mean this Steve:
call MY_CPPRoutine(chars,ok,cancel,xx) (from FORTRAN)
C++ code
extern "C "void MY_CPPRoutine (char[],bool*,bool*,double*);
class CRectangle
{
int x, y;
int area () {return(x*y);}
public:
double k;
void set_values (int,int,double*);
};
void CRectangle::set_values (inta,intb,double* k)
{
double m;
x = a;
y = b;
*k=area();
}
void MY_CPPRoutine(char chars[],bool*ok,bool*cancel,double*k)
{
CRectangle rect;
double m;
bool ok1,cancel1;
ok1=true;
cancel1=false;
*ok=ok1;
*cancel=cancel1;
strcpy(chars,"blah");
m=0;
rect.set_values (3,4,k);
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
An example that I think is along the lines of what is being discussed:
[cpp]//------------------------------------------------------------------------------
// Our C++ class.
class my_class
{
private:
int private_data;
public:
my_class(int new_data)
{
private_data = new_data;
}
int get_data() const
{
return private_data;
}
void set_data(int new_data)
{
private_data = new_data;
}
};
//------------------------------------------------------------------------------
// Accessor functions for Fortran to call.
// Wrapper for my_class::get_data.
extern "C" int my_class_get_data(my_class* object_ptr)
{
return object_ptr->get_data();
}
// Wrapper for my_class::set_data.
extern "C" void my_class_set_data(my_class* object_ptr, int new_data)
{
object_ptr->set_data(new_data);
}
// Constructs a new my_class object on the heap.
extern "C" my_class* my_class_new(int new_data)
{
return new my_class(new_data);
}
// Frees a my_class object previously created with my_class_new.
extern "C" void my_class_delete(my_class* object_ptr)
{
delete object_ptr;
}
[/cpp]
[fortran]PROGRAM UseMyClass
USE, INTRINSIC :: ISO_C_BINDING, ONLY: C_PTR, C_INT
IMPLICIT NONE
INTERFACE
FUNCTION get_data(object_ptr) BIND(C, NAME='my_class_get_data')
USE, INTRINSIC :: ISO_C_BINDING, ONLY: C_PTR, C_INT
IMPLICIT NONE
TYPE(C_PTR), INTENT(IN), VALUE :: object_ptr
INTEGER(C_INT) :: get_data
END FUNCTION get_data
SUBROUTINE set_data(object_ptr, new_data) BIND(C, NAME='my_class_set_data')
USE, INTRINSIC :: ISO_C_BINDING, ONLY: C_PTR, C_INT
IMPLICIT NONE
TYPE(C_PTR), INTENT(IN), VALUE :: object_ptr
INTEGER(C_INT), INTENT(IN), VALUE :: new_data
END SUBROUTINE set_data
FUNCTION new(new_data) BIND(C, NAME='my_class_new')
USE, INTRINSIC :: ISO_C_BINDING, ONLY: C_PTR, C_INT
IMPLICIT NONE
INTEGER(C_INT), INTENT(IN), VALUE :: new_data
TYPE(C_PTR) :: new
END FUNCTION new
SUBROUTINE delete(object_ptr) BIND(C, NAME='my_class_delete')
USE, INTRINSIC :: ISO_C_BINDING, ONLY: C_PTR
IMPLICIT NONE
TYPE(C_PTR), INTENT(IN), VALUE :: object_ptr
END SUBROUTINE delete
END INTERFACE
TYPE(C_PTR) :: object_ptr
!*****************************************************************************
object_ptr = new(1_C_INT)
PRINT "('get_data says:',I0)", get_data(object_ptr)
CALL set_data(object_ptr, 2_C_INT)
PRINT "('get_data says:',I0)", get_data(object_ptr)
CALL delete(object_ptr)
END PROGRAM UseMyClass
[/fortran]
The use of bare pointers in C++, and to a lesser extent, bare C_PTR's on the Fortran side, are things that I'd consider avoiding or wrapping, from a code robustness point of view, but that might start to obscure the example.

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page