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

Using .NET to Create a Dataset in Fortran - Can I do it?

picman
Beginner
931 Views

I need to access a SQL table in my Fortran code. Can I create a dataset much like I would do in VB.NET?

Something along the lines of using the OLEDBConnectionthe OLEDDBataAdapter?

If not, I am thinking I would do this in Vb and then call my subroutine to process each Row in the SQL table.

Thanks.

0 Kudos
11 Replies
Steven_L_Intel1
Employee
931 Views

There are a variety of ways to do this. The most straightforward approach is to use the unsupported freeware f90SQL. You can also use COM or .NET to access tools such as ACCESS or EXCEL, but that requires understanding the COM/.NET programming model and some advanced coding on your part. The "Intel Fortran Module Wizard" tool will create interfaces for COM and .NET applications and there are library routines to help you manipulate objects.

0 Kudos
picman
Beginner
931 Views

There are a variety of ways to do this. The most straightforward approach is to use the unsupported freeware f90SQL. You can also use COM or .NET to access tools such as ACCESS or EXCEL, but that requires understanding the COM/.NET programming model and some advanced coding on your part. The "Intel Fortran Module Wizard" tool will create interfaces for COM and .NET applications and there are library routines to help you manipulate objects.


Thanks for your input. You mention I could use COM or .NET (that is what I want to use) to access tools such as ACCESS. Does this mean I can access other OleDBs much as I woudl in VB.NET?

For instance, something like this (an abbreviate form) is what I would in VB.NET.

Dim con As New OleDb.OleDbConnection

Dim ds As New DataSet
Dim da As OleDb.OleDbDataAdapter

con.ConnectionString = "PROVIDER=Microsoft.Jet.OLEDB.4.0;Data Source = C:AddressBook.mdb"

sql = "SELECT * FROM tblContacts"

da = New OleDb.OleDbDataAdapter(Sql, con)

da.Fill(ds, "AddressBook")

0 Kudos
Steven_L_Intel1
Employee
931 Views

Yes, you could. It's not that simple, though. For something like that, give F90SQL a whirl first.

0 Kudos
picman
Beginner
931 Views

Yes, you could. It's not that simple, though. For something like that, give F90SQL a whirl first.

Again thanks.
Your suggestion of using the f90sql is good, but I am certain my management will not agree to usingF90SQL for several reasons. I am under the impression it is using ODB vs OLE is one issue and I am certain they will not want to rely upon f90sql.
So, I am going to persue using a VB.NET program to open the dataset and access each row, calliing my fortran routine with the row data as a string argument.
I know there are references in the help for using multiple languages and that I will be making a DLL from my fotran code and that the VB.NET program will be referencing that DLL.
Most of the examples and references are for C and Fotran. Can you point me in the right direction for calling a Fotran routine from VB? Is there perhaps a template or something?
The actual final goal of this is to use this software as a CLR module in SQL. I am not 100% certain if this will be possible, even if I call the routine from VB.
But my first goal is to eiminate the exporting of data from SQL into a flat file for my existing Fortran to process. So I want to be able to "read" the SQL data directly.
0 Kudos
Steven_L_Intel1
Employee
931 Views

There are two samples provided of calling Fortran from VB. The on-disk documentation regarding mixed-language programming is a worthwhile read.

0 Kudos
picman
Beginner
931 Views

There are two samples provided of calling Fortran from VB. The on-disk documentation regarding mixed-language programming is a worthwhile read.

My message looked even more horrible after I sent it. I had editted out the double spacing of lines for the most part, but when I sent it, it came out spaced out multiple times and some lines were broken. Sorry about that. Is there a better way to copy the code in? I noticed a single C/R when typing shows up double spaced in the composing window, but not when I send it.

0 Kudos
Steven_L_Intel1
Employee
931 Views

Use the "Insert Code" button in the toolbar - the one with a pencil. That works pretty well. Leave the language as C++.

0 Kudos
picman
Beginner
931 Views

Use the "Insert Code" button in the toolbar - the one with a pencil. That works pretty well. Leave the language as C++.

Thanks. Sorry for the mess. I am sure it is hard looking at a lot of problems without trying to sort thru that.

I narrowed my problem down to the passing of string arguments. I modified my Fortran DLL to simply pass back an integer value and that works. I left the string vars as arguments and just added the integer value.

I do recall seeing somewhere that there are issues with string variables - the fact that Fortran sets them as fixed length and VB sets them as variable length.

I have included my source one more time per your instructions. With luck, this is actually a simple problem.

[cpp]Public Class Form1

    Declare Auto Sub FORTRANTEST Lib _
    "C:Documents and SettingschrisMy DocumentsVisual Studio 2008ProjectsDll1Dll1releasedll1.dll" _
    Alias "FORTRANTEST" (ByRef Street_In As String, ByRef Street_Out As String, ByRef i As Integer)


    Private Sub OpenSqlTbl_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OpenSqlTbl.Click
        Dim con As New OleDb.OleDbConnection
        Dim ds As New DataSet
        Dim da As OleDb.OleDbDataAdapter
        Dim sql As String
        Dim i, j As Integer
        Dim Street_out As String
        Dim Street_in As String

        'con.ConnectionString = "provider=sqloledb;server=Chris_at_home2;database=hh1;integerated security=sspi"
        con.ConnectionString = "Provider=sqloledb;Data Source=MSGExpDev;Initial Catalog=nmrkeydatabase;Integrated Security=SSPI;"
        con.Open()

        sql = "select top 10 Primaddress from dbo.tblmatchdata"
        da = New OleDb.OleDbDataAdapter(sql, con)

        da.Fill(ds, "dbo.tblmatchdata")

        con.Close()

        i = 0
        Street_out = " "
        Do While i < 5
            MsgBox("row " & i.ToString & " " & ds.Tables("dbo.tblmatchdata").Rows(i).Item("primaddress") & "*")
            Street_in = ds.Tables("dbo.tblmatchdata").Rows(i).Item("primaddress") & "*"
            MsgBox(Street_in & "*")
            Street_out = Street_in
            Call FORTRANTEST(Street_in, Street_out, j)
            MsgBox("out " & Street_out & "*" & j.ToString)
            i = i + 1
        Loop

    End Sub
End Class
[/cpp]

======

FORTRAN CODE:

[cpp]!  Dll1.f90 
!
!  FUNCTIONS/SUBROUTINES exported from Dll1.dll:
!  Dll1 - subroutine 
!
subroutine FortranTest(Street_In, Street_Out, i)

  ! Expose subroutine Dll1 to users of this DLL
  !
  !DEC$ATTRIBUTES DLLEXPORT:: FORTRANTEST
  !DEC$ATTRIBUTES ALIAS: 'FORTRANTEST':: FORTRANTEST
  !DEC$ATTRIBUTES STDCALL,REFERENCE:: FORTRANTEST

    character*(*)    Street_In, Street_Out
    Integer*4   i
    
    i = 1
    Street_Out =  'Yea!'
   Return

 ! Body of Dll1

end subroutine FortranTest
[/cpp]

0 Kudos
picman
Beginner
931 Views

Use the "Insert Code" button in the toolbar - the one with a pencil. That works pretty well. Leave the language as C++.

I found a reference to this problem and your advice from Oct 26, 2005. I modified my VB code to pass the length of the strings BY_VAL following the string arg which is passed BY_REF.

This is better. But I get memoryaccess violations on the return string, most likely. Since I am passing the len by val I am suspecting the Fortran is trying to set that length on the return and that is not working. I have included what is undoubtedly the key pieces of code here. You can probably ignore the previous post with all of my VB test code. I did not delete the post just in case it is needed.

[cpp] Declare Auto Sub FORTRANTEST Lib _
    "C:Documents and SettingschrisMy DocumentsVisual Studio 2008ProjectsDll1Dll1releasedll1.dll" _
    Alias "FORTRANTEST" (ByRef Street_In As String, ByVal Street_In_len As Integer, _
                         ByRef Street_Out As String, ByVal Street_Out_len As Integer, ByRef i As Integer)[/cpp]

I tried using a variable for the length, hoping that would work.

[cpp]k = Street_out.Length
            Call FORTRANTEST(Street_in, Street_in.Length, Street_out, k, j)[/cpp]

The DLL:

[cpp]!  Dll1.f90 
!
!  FUNCTIONS/SUBROUTINES exported from Dll1.dll:
!  Dll1 - subroutine 
!
subroutine FortranTest(Street_In, Street_Out, i)

  ! Expose subroutine Dll1 to users of this DLL
  !
  !DEC$ATTRIBUTES DLLEXPORT:: FORTRANTEST
  !DEC$ATTRIBUTES ALIAS: 'FORTRANTEST':: FORTRANTEST
  !DEC$ATTRIBUTES STDCALL,REFERENCE:: FORTRANTEST
    Integer*4   i
    character*(*)    Street_In, Street_Out
   
    i = 1
    Street_Out =  'Yea!'
   Return

 ! Body of Dll1

end subroutine FortranTest
[/cpp]

0 Kudos
Steven_L_Intel1
Employee
931 Views

I'll admit that I don't have all the details fresh in my mind, but.. If you want the Fortran code to return a string value to VB you must pass the VB string by reference and accept it as a "BSTR". You'd then use the supplied routines for reading and writing BSTRs. See the VB.NET-Safearrays sample for an example of doing this (you can omit the code dealing with SAFEARRAYs.)

0 Kudos
picman
Beginner
931 Views

I'll admit that I don't have all the details fresh in my mind, but.. If you want the Fortran code to return a string value to VB you must pass the VB string by reference and accept it as a "BSTR". You'd then use the supplied routines for reading and writing BSTRs. See the VB.NET-Safearrays sample for an example of doing this (you can omit the code dealing with SAFEARRAYs.)

Thanks. I will check this out. So there is hope. I will let you know how I make out.

0 Kudos
Reply