Software Archive
Read-only legacy content
17060 Discussions

com server array shape`

rahzan
New Contributor I
1,662 Views
The Com server wizard asks for the explicit dimensions of Array arguments. Is it possible to give it assuemd or allocatable arrays? I assumed that it passes arrays as safearrays anyway.

If this is possible, how should one specify the dimension(s) in either the case of assume size (perhaps w. the size also passed) or allcoatable or...

Any hints will be appreciated,
Tim
0 Kudos
6 Replies
rahzan
New Contributor I
1,662 Views
OK so I decided to bravethe elements and try this out.
I added anew interface to the sample ADDER server to add arrrays. It worked fine as called from VB with a fixed dimension of 10

next I changed the object datatype to one like:

integer size
real,allocatable:: dataarray(:)

Now this requires a parameter in the constructor to set the size and allocate the array, all this is fine except that there is no place in the com server wizd to tell it the contructor takes an argument (something perfectly ordinary). In fact this is manifested in the fact that the call to the construcor is CLSFCT.f90 needs to be modified yet CLSFCT is a not-to-be-edited file.

Da wondez never cease.

Any ideas will be appreciated.
Tim
0 Kudos
Intel_C_Intel
Employee
1,662 Views
Hi Tim,

Support for assumed shape arrays was added in V6.6. There is a checkbox that you select when defining an array argument to specify that the array is assumed shape.

With regards to the "Do not Edit" files, they get completely re-generated every time that you modify the server definition, destroying any changes that you may have made.

Below is a section from the latest documentation - it may have been added in V6.6, I don't remember.

Leo

Discussion of Wizard Code Generation

The Wizard generates the code for your project from the files in the subdirectory of your project named project-nametemplates. The project-name.hie file contains the definition of your COM server in an undocumented text language. You should not manually edit the project-name.hie file ? the Wizard does this for you.

Most of the other files in the project-nametemplates directory are templates of the source files generated for your project. These templates contain source code that is copied "as-is" to the generated sources, and embedded directives that guide the Wizard in generating the code specific to the COM server that you define. The directives use the information in the project-name.hie file. The directives are undocumented and subject to change.

When you create a new Fortran COM Server project, the AppWizard creates the project-nametemplates directory and copies the templates from the Visual Fortran COM Server Wizard templates directory, ...Df98TemplatesCOMServer.

The files in the COM Server Wizard templates directory may change with each release of Visual Fortran, but the templates in your project-nametemplates directory are never automatically updated. For example, if you create a COM server using Visual Fortran Version 6.5 and the next release of Visual Fortran (such as Version 6.5A) contains updated templates, the templates for your COM server are not automatically updated to the new 6.5A templates. If you modify the definition of your server, your project continues to use the 6.5 templates that it was created with. This has the advantage of not introducing different code into a project that you have developed and tested.

However, there are two cases where you may want to modify the templates that are used by your project:

A new release of Visual Fortran may contain additional features that can be used in your COM server project. Some of the new features may depend upon the new templates. These features will not be available to a pre-existing project unless you update the templates in the project-nametemplates directory. You do this by copying all of the files in the Visual Fortran COM Server Wizard templates directory ...Df98TemplatesCOMServer into the project-nametemplates directory, replacing all files with the same name. Your project will then use the new templates the next time that the definition of your server is modified and the project sources are regenerated.
When you want to modify the code generated by the Wizard. You may edit a template in your project-nametemplates directory. Editing code that is copied "as-is" is straight forward. Attempting to modify the embedded directives is unsupported and could cause the Wizard to fail when using the modified template. The embedded directives begin with an @ (at-sign) character. The next character determines the type of directive. The end of many directives is also delimited by an @ character followed by the mat ching end character for the type of directive. For example, @[ and @] are the delimiters for one type of directive.
The advantage of modifying a template is that you can customize the code generated by the Wizard. The disadvantages of modifying a template are:

You must be very careful not to modify a template in a manner that causes the Wizard to generate bad code or fail.
You will not be able to update the project templates with the templates from a new release of Visual Fortran without having to re-apply your modifications to the new templates.
0 Kudos
rahzan
New Contributor I
1,662 Views
Thanks Leo,
1.Most importantly I'd like to find out if there is a way to feed the CONSTRUCTOR arguments, in this case the size of an array. Are ou saying that either this is not a good way of constructing an array object or that it simply is not possible in cvf 6.6?

2. The assumed size checkbox in the properties panel is grayed out, will this become available if the templates are updated?

3. I did notice that the tremplates for the ADDER are older (2/00) than the ones in the (now upgraded) templates folder(12/00). I assume that this is because the ADDER samlpe was not updated during the upgrade and I'm still using the templates from the 6.5 sample... Now even if I can specify an assumed size array as an argument to some ol' method (e.g. the ADD method) it still does not set the object data-type which needs to be done in the constructor and not just the operand...

Finally, Maybe this is a way to do it: (in the context of the ADDER sample)
a) decalre the datatype to include an allocatable array (as I indicated in my previous msg)
b) Leave the constrcutor as a do nothing routine (which is a shame)
c) and require the client to ALWAYS immediatelycall a set_property method to pass the size of the array and the set_property will allocate the object array.
d) finally the operand is dimensioned using the object-datatype.size to guarantee compatible length with the object-array (e.g. "currentvalue in the Adder example).
I have not tried this, but if I missed your point PLEASE write again.
This is an ugly (terribly un-OOP way) but if it will do the job, so be it.

At least let me know why the assumed size chack box is grayed.
Many Thanks,
Tim
0 Kudos
Intel_C_Intel
Employee
1,662 Views
Hi Tim,

> 1.Most importantly I'd like to find out if there is a way to feed the CONSTRUCTOR arguments

I was initially thinking that you could modify the templates yourself to do this, but after thinking a little more, this is actually a COM design restriction. That is, there is no way to pass arguments to the object creation routine (e.g. CoCreateInstance).

> 2. The assumed size checkbox in the properties panel is grayed out, will this become available if the templates are updated?

Yes, that is exactly what is happenning. The assumed shape array support requires the V6.6 templates.

> 3. I did notice that the tremplates for the ADDER are older (2/00) than the ones in the (now upgraded) templates folder(12/00). I assume that this is because the ADDER samlpe was not updated during the upgrade and I'm still using the templates from the 6.5 sample... Now even if I can specify an assumed size array as an argument to some ol' method (e.g. the ADD method) it still does not set the object data-type which needs to be done in the constructor and not just the operand...

You are correct about the ADDER sample. So, the data type of the array is variable? If so, you might want to consider making the argument a VARIANT and deal with the Win32 SafeArray* routines to get at the data.

I hope this helps,
Leo
0 Kudos
rahzan
New Contributor I
1,662 Views
Thanks Leo,
Your reply was useful to the end that The whole contuctor thing is kind of a useless place holder and it cannot be used to really constrauct anpbject inthe usual sense.

I had hoped that youwould coment on my "solution' listed at the bottom of the the msg last. I have written it out and it compiles just fine but shows very simple but strange behavior. I apologize in advacebut I cannot resist but to post it here.

Here ishe instancedata module:
The constructor does nothing but to open a text file. I have skipped the desctruror which would only close the said file.
!
! UHedgeHogOpsTY.f90 - This module contains user-defined class definitions and methods
!

module HedgeHogOps_USE

type HedgeHogOps_InstanceData
sequence
integer Size
real,allocatable:: CurrentArray(:)
end type
contains
==================================================================!
function HedgeHogOps_CONSTRUCTOR( ObjectData ) result (hresult)
use dfwinty
implicit none
type(HedgeHogOps_InstanceData) ObjectData
!dec$ attributes reference :: ObjectData
integer(LONG) hresult
OPEN(1,FILE='logofHedgeHog.txt')
hresult = S_OK
All initialization is done in Set_Size method
end function

end module

Now here is the implementation:
!
! UIHedgeHogOps.f90 - This file contains the implementation of the
! IHedgeHogOps methods
! IHedgeHogOps_get_Size
!================================================================== ! IHedgeHogOps_put_Size
! function IHedgeHogOps_put_Size( ObjectData , ArraySize) result (hresult)
! use HedgeHogOps_Types
! implicit none
! type(HedgeHogOps_InstanceData) ObjectData
! !dec$ attributes reference :: ObjectData
! INTEGER(4), intent(in) :: ArraySize
! integer(LONG) hresult
! ObjectData.Size=Arraysize
! allocate(ObjectData.CurrentArray(Arraysize))
! ObjectData.CurrentArray=0.
! hresult = S_OK
! end function
!=======================================================
function IHedgeHogOps_setArraySize( ObjectData , arraySize) result (hresult)
use HedgeHogOps_Types
implicit none
type(HedgeHogOps_InstanceData) ObjectData
!dec$ attributes reference :: ObjectData
INTEGER(4), intent(in) :: arraySize
integer(LONG) hresult

write(1,*)'SetSize called with size=',arraySize

! if(.not.allocated(ObjectData.CurrentArray) .and. arraySize /= 0)then
ObjectData.size=arraysize
allocate(ObjectData.CurrentArray(arraySize))
ObjectData.currentArray=0.
hresult = S_OK
! else
! hresult = -1
! endif
end function
================================================================== ! IHedgeHogOps_getArraySize
function IHedgeHogOps_getArraySize( ObjectData , currArraySize) result (hresult)
use HedgeHogOps_Types
implicit none
type(HedgeHogOps_InstanceData) ObjectData
!dec$ attributes reference :: ObjectData
INTEGER(4), intent(out) :: currArraySize
integer(LONG) hresult

currArraySize = size(ObjectData.CurrentArray,1)
write(1,*)'getSize called returning value=',currArraySize
hresult = S_OK
end function
==================================================================
! IHedgeHogOps_AddInputArray
function IHedgeHogOps_AddInputArray( ObjectData , InputArray) result (hresult)
use HedgeHogOps_Types
implicit none
type(HedgeHogOps_InstanceData) ObjectData
!dec$ attributes reference :: ObjectData
Real(4), intent(inout) :: InputArray(ObjectData.size)
! DIMENSION InputArray(1:)
integer(LONG) hresult

0 Kudos
rahzan
New Contributor I
1,662 Views
oh poo....It seems like after crefully formatting the text I somehow lost all the CRLF's.
Please let me know if i should repost or email the sample code.

Thanks, Tim
0 Kudos
Reply