- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi!
I'm involved in a software project where I need to integrate several Fortran 90/95 models with a C++ modeling framework. The framework uses an extensive class heirarchy to be able to model a variety of scenarios. My question is: Is it possible to provide access to a C++ class and its interface to Fortran through .NET?
Example:
class XYZ
{
//...
virtual void add_to(int x) = 0;
virtual unsigned int size() = 0;
//...
};
class V : public XYZ
{
//...
virtual void add_to(int x);
virtual unsigned int size();
//...
};
void main()
{
XYZ *b = new V();
Results *r1 = CPP_MODEL_AND_MODIFY(b);
Results *r2 = FORTRAN_MODEL(b);
Compare(r1, r2);
}
The CPP_MODEL and FORTRAN_MODEL calls are what I'd like to be able to do. The Fortran code would access some data elements in "b".
Is this possible to do with .NET? Is this possible to do at all?
If so, can someone provide me with a few examples? I see how I can do simple integration with structs, but not with classes.
Thanks!
Nils
I'm involved in a software project where I need to integrate several Fortran 90/95 models with a C++ modeling framework. The framework uses an extensive class heirarchy to be able to model a variety of scenarios. My question is: Is it possible to provide access to a C++ class and its interface to Fortran through .NET?
Example:
class XYZ
{
//...
virtual void add_to(int x) = 0;
virtual unsigned int size() = 0;
//...
};
class V : public XYZ
{
//...
virtual void add_to(int x);
virtual unsigned int size();
//...
};
void main()
{
XYZ *b = new V();
Results *r1 = CPP_MODEL_AND_MODIFY(b);
Results *r2 = FORTRAN_MODEL(b);
Compare(r1, r2);
}
The CPP_MODEL and FORTRAN_MODEL calls are what I'd like to be able to do. The Fortran code would access some data elements in "b".
Is this possible to do with .NET? Is this possible to do at all?
If so, can someone provide me with a few examples? I see how I can do simple integration with structs, but not with classes.
Thanks!
Nils
Link Copied
3 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I suggest that you don't try direct access, as internal structure of a class is a) complicated b) compiler-dependent, while class member functions are not the same beast as "plain" "C-style" functions.
Instead, you can treat the class object in Fortran as an opaque object (e.g. pointer to "something"), and write plain C-style wrappers for accessing required members from Fortran (primary types or structs). For example:
Code:
class XYZ { //... virtual void add_to(int x) = 0; virtual unsigned int size() = 0; //... }; //C-style wrappers void XYZadd_to(XYZ& xyz, int x) { xyz.add_to(x); } //C-style wrappers unsigned int XYZsize(XYZ& xyz) { return xyz.size(); } Fortran code: ! Dummy type module M_XYZty type T_XYZ integer dummy !You don't need it, but I'm not sure !if empty TYPE is allowed end type T_XYZ end module M_XYZty !-------------------- module M_XYZ use M_XYZty interface subroutine XYZadd_to(xyz, x) !DEC$ATTRIBUTES C, DECORATE, ALIAS: "XYZadd_to":: XYZadd_to !DEC$ATTRIBUTES REFERENCE:: xyz use M_XYZty type(T_XYZ):: xyz integer:: x end interface interface integer function XYZsize(xyz) ... end interface end module M_XYZ !===================== subroutine CalledFromC(xyz) use M_XYZ call XYZadd_to(xyz, 1) iSize = XYZsize(xyz) end subroutine CalledFromC
The idea is that Fortran never ever knows what's the exact format of class XYZ -- all it does is that it receives a reference to it and calls C-stylewrappersto access/manipulate the data.If you want to have a set ofmembers to be accessible from Fortran, it's probably a good idea to pack it in a struct and dedicate a C-style wrapper to provide access to it...
(continued in next post, the Forum has problems with two src sections within one post).
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
...here it is:
Code:
struct PUBLICDATA { ... } class XYZ { ... public PUBLICDATA PublicData; } void XYZGetPublicData(XYZ& xyz, PUBLICDATA** ppPublicData) { *ppPublicData = &xyz.PublicData; } !============= !In Fortran code, declare T_PUBLICDATA & write the interface: interface subroutine XYZGetPublicData(xyz, pPublicData) !DEC$ATTRIBUTES C, ALIAS: ... use M_XYZty !DEC$ATTRIBUTES REFERENCE:: xyz type(T_XYZ):: xyz type(T_PUBLICDATA), POINTER:: pPublicData end subroutine end interface !usage: subroutine CalledFromC(xyz) ... type(T_PUBLICDATA), POINTER:: pPD call XYZGetPublicData(xyz, pPD) !Now, you obtained the pointer to xyz.pPublicData and you can !access it directly both for reading (AND writing, which can !also be a way to shoot yourself in foot): something = pPD%foo; pPD%whatever = somethingElse; end subroutine CalledFromC
Here, I (ab)used the fact that a scalar Fortran POINTER is implemented in CVF/IVF as void*, i.e. a 32-bit address. Thus, implementation of C++ XYZGetPublicData and its Fortran interface are compatible (PUBLICDATA** <-> type(T_PUBLICDATA), POINTER). Don't try this with arrays though.
Jugoslav
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Jugoslav!
Thanks a whole bunch - it's very helpful.
Nils
Thanks a whole bunch - it's very helpful.
Nils

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