Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

COM Question

klaus_knebel
Beginner
669 Views
Hello

I have a problem which is difficult for me to explain, because I am not very familiar with COM programming.

I am writting a program which uses COM for data tranfer between my programm a another (commercial) programm.
I use Com Wizard to translate the .tbl file.
This works fine so far.

Now I have to use the method rsGetStructuralData2()
which is somehow derived from method rsGetStructuralData()

I wrote to the programmer of the (commercial) programm and a said that I need a method rsGetStructuralData2()

Here is his anwer:
............................
no method rsGetStructuralData2() is needed in COM.
You only have to convert interface returned by method rsGetStructuralData() to new interface IrsStructuralData2.
It works without problems and it is standard behavior.

VisualBasic:
Dim SData2 as IrsStructuralData2
Set SData2 = RSStr.rsGetStructuralData

C# .NET:
IrsStructuralData2 SData2 = RSStr.rsGetStructuralData as IrsStructuralData2

or

IrsStructuralData2 SData2 = (IrsStructuralData2)RSStr.rsGetStructuralData

This new interface IrsStructuralData2 is derived from old interface IrsStructuralData. It means it contains all methods from old one.
In .NET, Excel VB, C++ it works without problems. But It seems in Fortran there is a problem.

......................

Question : How can I do that in fortran ?

Klaus
0 Kudos
8 Replies
klaus_knebel
Beginner
669 Views
Hi
It seem, that my problem is difficult
or noboy understands what I mean
Klaus

0 Kudos
Steven_L_Intel1
Employee
669 Views
I, at least, don't understand the question. What you write about "extending" implies object-oriented programming such as C++ classes. Perhaps the author was telling you to use class extension to create this new method. That isn't an appropriate approach for Fortran.

I'm sure that whatever you need can be done in Fortran, but I think we'll need more information, such as what the original interface looks like and what it is you want to extend it to. So far, nothing you have written about is COM-related other than perhaps that you used the Module Wizard to create some interfaces. Maybe all you need is a jacket routine of some sort around one of the existing generated routines.
0 Kudos
klaus_knebel
Beginner
669 Views
Steve
I try to explain better.

I do convert a .tbl file using the Com Wizard.
The output of the Com Wizard is a fortran file containing the interfaces and Functions
which I use to 'connect' the 2 programms.
One of them is my program
Ok so far.

Now there is a Interface called IrsStructuraldata.
----------------------------------------
INTERFACE
!Gets interface to Structural Data.
INTEGER(4) FUNCTION IrsStructure_rsGetStructuralData($OBJECT, ppIData)
INTEGER(INT_PTR_KIND()), INTENT(IN) :: $OBJECT ! Object Pointer
!DEC$ ATTRIBUTES VALUE :: $OBJECT
INTEGER(INT_PTR_KIND()), INTENT(OUT) :: ppIData ! IUnknown
!DEC$ ATTRIBUTES REFERENCE :: ppIData
!DEC$ ATTRIBUTES STDCALL :: IrsStructure_rsGetStructuralData
END FUNCTION IrsStructure_rsGetStructuralData
-----------------------------------------------


Calling this interface gives me the 'pointer' (ppIData) which I use further
on to call the 'Members' of this interface.

Ok so far no problem, it works fine.

Now there is another Interface called IrsStructuraldata2.
It contains the same Methodes as IrsStructuraldata plus 2 more methodes.
(It is somehow derived from IrsStructuraldata)

Now if I want to use methodes of IrsStructuraldata2 I first need to get the pointer to IrsStructuraldata2
the same way as shown above for IrsStructuraldata. (At least I think so ?)

But I do not have an Interface to IrsStructuraldata2.
This is the problem.
The answer of the programmer you can see in my fist post above.
He tells me how to do it using VisualBasic or C#.Net.
But he does not kow how to do it in Fortran.

Using the same pointer as for IrsStructuraldata gives me an error.

Now, how can I derive IrsStructuraldata2 from IrsStructuraldata ?

Klaus
0 Kudos
Steven_L_Intel1
Employee
669 Views
When you extend a class, you effectively create a new class that contains all of the routines/methods of the old class (and its class variables), plus any new ones you add. I do not pretend to be an expert at this, but it seems to me that just extending a class without adding to it is nothing more than giving a different name to the old class. (I hope those more familiar with C++ will chime in if I'm mangling this.)

Where do the two new methods come from? Not simply from extending the class, I'd think.
0 Kudos
Peter_Priestley
Beginner
669 Views

Klaus,

I think you are saying that the COM type library contains multiple COM interfaces.

In that case you should have seen 'IrsStructuralData2' listed on the second page of the Fortran module wizard, and you need to select it or 'Select All' in the wizard.

If the generated code doesn't contain any references to IrsStructuralData2 it's likely it wasn't selected in the module wizard.

Another approach, if you look at the COM library with the 'OLE Object Viewer' that comes with Visual Studio, can you see the IrsStructuralData2 interface?

Regards,

Peter P.

0 Kudos
klaus_knebel
Beginner
669 Views
Peter

Thanks for your reply.

The interface 'IrsStructuralData2' is listed in the Com Wizard.
And I do select them all.

What I am missing is a function that gives me the 'pointer' to that interface.

I need something like the following interface to 'IrsStructuralData'
---------------------------------------------------
INTERFACE
!Gets interface to Structural Data.
INTEGER(4) FUNCTION IrsStructure_rsGetStructuralData($OBJECT, ppIData)
INTEGER(INT_PTR_KIND()), INTENT(IN) :: $OBJECT ! Object Pointer
!DEC$ ATTRIBUTES VALUE :: $OBJECT
INTEGER(INT_PTR_KIND()), INTENT(OUT) :: ppIData ! IUnknown
!DEC$ ATTRIBUTES REFERENCE :: ppIData
!DEC$ ATTRIBUTES STDCALL :: IrsStructure_rsGetStructuralData
END FUNCTION IrsStructure_rsGetStructuralData
END INTERFACE
POINTER(IrsStructure_rsGetStructuralData_PTR, IrsStructure_rsGetStructuralData) ! routine pointer
-------------------------------------------------------
-

I have told this to the programmer of the .tbl library and his answer is show in my first post.

Part of his answer is :
............................
no method rsGetStructuralData2() is needed in COM.
You only have to convert interface returned by method rsGetStructuralData() to new interface IrsStructuralData2.
..................................

He tell me how to do it in VB or C but he does not know Fortran.

Sorry, but my explanation of the problem is not clear, because I do not know much about COM

Klaus
0 Kudos
Peter_Priestley
Beginner
669 Views

OK, there are 3 interfaces,

IrsStructure
IrsStructuralData
IrsStructuralData2

There is a method IrsStructure.rsGetStructuralData() that is supposed to return a pointer to a contained IrsStructuralData (or IrsStructuralData2) object.

It seems that IrsStructuralData2 may be an aggregation of IrsStructuralData (which is the COM way of saying it inherits all the IrsStructuralData methods).

The programmer suggests the pointer may be 'cast' to an IrsStructuralData2 pointer, but as Fortran isn't strongly typed like C++ or C# there is no mechanism to cast the pointer. The pointer is an INTEGER(4).

You say using the pointer to call the IrsStructuralData2 methods fails. Can you call any of the methods common to IrsStructuralData and IrsStructuralData2?

Are you sure the IrsStructure object has been created correctly, i.e. using COMCreateObject() ? Has any application specific initialization been done in IrsStructure? The application documentation should tell you what needs to be done before you can get a valid pointer back from the IrsStructure.rsGetStructuralData() method.

Other questions which spring to mind (Intel's COM expert might like to answer!)-

- Does the Module Wizard generated code have good support for aggregated objects?

- Does the code support object instances that aren't explicitly created using COMCreateObject()?

Regards,

Peter P.

0 Kudos
klaus_knebel
Beginner
669 Views
Hi Peter
yes, you got the point of my problem.

IrsStructuralData2 has the same methods as IrsStructuralData plus 2 more.
IrsStructuralData and all the other interfaces work fine, no problem.

I do not use COMCreateObject(). Do I need that ?
Here is a sequence of Code that I use and which works fine.

CALL COMINITIALIZE(hRes)
CALL COMCLSIDFromProgID ("RSTAB6.Structure", clsid, status)
CALL COMGetActiveObjectByGUID (clsid, IID_IrsStructure, pos, hres)
hres = $IrsStructure_rsGetApplication (pos, ppApplication)
hres = $IrsApplication_rsGetActiveStructure (ppApplication, ppIrsStructure)
hres = $IrsStructure_rsGetStructuralData (ppIrsStructure, ppIrsTopology)
.
.
hres = $IrsStructuralData_rsFinishModification (ppIrsTopology)


==> this works fine

Now I need to use one of the methodes from IrsStructuralData2

hres = $IrsStructuralData2_rsFinishModificationEx(ppIrsTopology, .false.)

==> this does not work because pointer ppIrsTopology is wrong
(I guess)

I guess there is no 'work around' in fortran for that.

Klaus
0 Kudos
Reply