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

VB.NET calling Fortran COM server

Teus_v_
Beginner
659 Views

I created a Fortran COM server and one of the subroutines has as input (among others) an array with strings.This used to work very well when called by a VB.NET program (and all other kind programs, like VBA in Excel, C++, other Fortran programs, etc.), but now it seems have problems because it crashes somewhere in the Fortran COM server, at a point where the array of strings is extracted from the SafeArray of BSTR’s. I am now running Intel Parallel Studio XE 2016 Update 2 Composer Edition for Fortran Windows and Microsoft Visual Studio 2012. Wit an old PC, I checked with Intel Visual Fortran, Package ID: w_fcompxe_2013_sp1.2.1.176 (also with Visual Studio 2012), but there it has the same problems. 

On the VB.NET side I have code like this (the array Comp is causing the problems):
 
Dim ErrorMsg As New String("No errors")
Dim Comp(20) As String
Dim Conc(20) As Double
Dim fp As New FluidProp
 
fp.SetFluid("TPSI", 1, Comp, Conc, ErrorMsg)
 
Public Class FluidProp
 
   ' The FluidProp COM library
    Private fp As New FluidPropLib.FluidProp
 
   ' Procedure to define working fluid 
   Public Sub SetFluid(ByVal ModelName As StringByVal nComp As IntegerByVal Comp() As String, _
                        ByVal Conc() As DoubleByRef ErrorMsg As String)
      Dim sa_comp As System.Array = Comp
      Dim sa_conc As System.Array = Conc
      fp.SetFluid(ModelName, nComp, sa_comp, sa_conc, ErrorMsg)
   End Sub
 
End Class
 
On the Fortran COM server side (.hie file) I have defined for the array Comp::
 
Assumed shape: True
By Reference: True
Dimension[1]: 20
Dimensions: 1
Fortran Type: CHARACTER(*)
IDL Type: BSTR
Intent: [in]
Is Optional: false
 
 
Does anyone have any hunch what might be wrong here? Like I said, in the past it worked fine, now it does not anymore. Has something changed, maybe in the Fortran compiler, or, maybe in VB,NET? 
 
Best regards,
Teus van der Stelt
 
0 Kudos
11 Replies
Steven_L_Intel1
Employee
659 Views

I'm not aware of any changes in this area. Without a buildable and runnable test case it's hard to speculate further. I don't have a COM Server sample that uses strings, but I do have a VB calling Fortran DLL sample (it's MixedLanguage\VB.NET-SafeArrays in the provided sample bundle) that uses BSTRINGs and it still works fine.

0 Kudos
Teus_v_
Beginner
659 Views

I attached a test case that clearly shows the problem. Now, it does not crash if you run it. However, you can see that the array in Fortran has not been mapped correctly. The first element of the array in VB (at index 0) is not at the first position of the array in Fortran (i.e. index 1), but the element at the second position in VB (at index 1) is at the first position of the Fortran array.

Aside from the VB.NET COM client, there is also a Fortran COM client in the test case. The Fortran client works correctly. 

Teus

0 Kudos
IanH
Honored Contributor II
659 Views

The zip file does not contain any source.

0 Kudos
Teus_v_
Beginner
659 Views

Again the zip file. Must have gone something wrong while zipping….

0 Kudos
Teus_v_
Beginner
659 Views

Dear all,

 

 

Just curious if somebody had the opportunity to check my test case and was able to reproduce my problems?

Best regards,

Teus

 

0 Kudos
Steven_L_Intel1
Employee
659 Views

I spent some time looking at it but there were some additional steps needed to run the program and I ran out of time. I will try again.

0 Kudos
Steven_L_Intel1
Employee
659 Views

In your VB source, you have:

        Dim Comp(20) As String

If you run the debugger and ask VB how many elements are in this, it says 21! In other words, it dimensions the array (0:20) in Fortran terms.

On the Fortran side you say (in the .hie) that this is 1:20. The generated Fortran code looks at the incoming SafeArray descriptor and finds 21 elements. Because you said 1:20, it starts indexing at element 1 but goes for 21 elements. This means it runs off the end of the array and hilarity does not ensue. Note that it also copies the wrong elements as it skips the first one.

So... I think you got caught by a change from VB6 to VB as of VS2008. (See https://msdn.microsoft.com/en-us/library/5c1seyzc(v=vs.90).aspx)

One could argue that the COM Server Wizard's generated code should offset the index by the actual lower bound of the incoming array. If I can figure out how to create a small test case that shows the problem, I'll let the developers know. Issue ID is DPD200415372.

0 Kudos
Steven_L_Intel1
Employee
659 Views

It's not just running off the end of the array, but indexing the wrong values. You can edit this in IFP2.f90 at line 158, but any change you make in the .hie file will overwrite this.

A suggested edit is to replace:

        do i$Comp = 1, nb$Comp(1)
            i = ConvertBSTRToString(bstrs$Comp(i$Comp), f$Comp(i$Comp))
        end do 

with:

        do i$Comp = 1, size(f$comp)
            i = ConvertBSTRToString(bstrs$Comp(i$Comp-1), f$Comp(i$Comp))
        end do 

 

0 Kudos
Teus_v_
Beginner
659 Views

Dear Steve, thanks a lot! Tomorrow I am going to work on it. I'll let you know how I progress. 

Best regards,

Teus

0 Kudos
Teus_v_
Beginner
659 Views

 

Hi Steve,

It works! In my case (and maybe in general) I would propose to change the line from

i = ConvertBSTRToString(bstrs$Comp(i$Comp-1), f$Comp(i$Comp))

to

i = ConvertBSTRToString(bstrs$Comp(i$Comp+lb$Comp(1)-1), f$Comp(i$Comp)),

so that it works for both VB and Fortran clients programs. I checked for a C++ client too and there it also works well. I hope your developers can find a general solution for this because now I have to adjust several subroutines manually every time I change the .hie file, which is quite cumbersome. Also, after an array of strings is returned from the COM-server to VB, a similar adjustment has to made.

Best regards,

Teus

 

 
0 Kudos
Steven_L_Intel1
Employee
659 Views

Yes, that's a more general solution.

0 Kudos
Reply