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

using .net dll in visual fortran

ratzeputz
Beginner
2,027 Views
hi there.

first of all i have to say that my english is not the best so please be patient hehe.

now to my problem:
normallyi am a .net developer so i am completely new to the fortran world.
but i have to learn it for my job :)

i wrote a class library in vb.net to get,send and delete files from a server over ssh. in vb.net the library works well.

now i want to use this dll. within fortran and so i wrote an interface to load the dll and uses the specific methods.
heres the code example i already wrote as an console application:
-----------------------------

program test

use dfwin, only: LoadLibrary, GetProcAddress

integer(INT_PTR_KIND()) hk32Lib

interface

function SendFileToSSH (host,port,user,passWord,path,fileName,loadFromPath) Result (res)

!DEC$ ATTRIBUTES STDCALL, DECORATE, ALIAS : 'SendFileToSSH' :: SendFileToSSH

!DEC$ ATTRIBUTES REFERENCE :: host

!DEC$ ATTRIBUTES REFERENCE :: port

!DEC$ ATTRIBUTES REFERENCE :: user

!DEC$ ATTRIBUTES REFERENCE :: passWord

!DEC$ ATTRIBUTES REFERENCE :: fileName

!DEC$ ATTRIBUTES REFERENCE :: loadFromPath

! DEC$ ATTRIBUTES REFERENCE :: res

character(50) host

integer(4) port

character(50) user

character(50) passWord

character(256)fileName

character(50) loadFromPath

character(1024) res

end function SendFileToSSH

end interface

pointer(lpSendFileToSSH,SendFileToSSH)

hk32Lib=LoadLibrary("c:/temp/HandleSSH.dll"C)

lpSendFileToSSH = GetProcAddress(hk32Lib,"SendFileToSSH"C)

end program test
----------------

if i debugs this code i can see that lpSendFileToSSH getting 0 as value which is probably wrong i think.
can you help me finding out what i have done wrong?

best regards

0 Kudos
25 Replies
anthonyrichards
New Contributor III
1,602 Views
Apparently you have the name aliasing and decoration correct since your program clearly compiles and links OK.

Try terminating all the string arguments with CHAR(0) and see if that works. Visual Basic expects and delivers null-terminated strings.
0 Kudos
Steven_L_Intel1
Employee
1,602 Views
Please show us the description of the SendFileToSSH routine from VB. I suspect that VB.NET wants a BSTRING rather than a normal character string. You'd have to call routines for creating BSTRINGs that can be found in module IFCOM (or DFCOM if you are using CVF.)
0 Kudos
ratzeputz
Beginner
1,602 Views
Hi all and thank you all for your answers.
The program itselfs compiles and links correct so there is no syntax error hehe.
@Steve:
I am sorry but i cant copy the code to the Forum before wednesday. But what i can tell you is, that all parameters are expected as a vb.net string except for the port (its an 32bit integer), and the function returns a string with error message if there is any error or "success" if everything worked fine during the transfer.
BSTRING means binary string right?
vb.net does support this as i can set the incoming parameters as a binary string and also can return the string as binary string.
am i right with my understanding?
0 Kudos
anthonyrichards
New Contributor III
1,602 Views
BSTR is a 'Bit string' which, for an n character string, as well as being stored as n characters as 2xn bytes, 2 per character (unicode I believe), stores the number of characters as 4 bytes immediately before the first character. So a BSTR consists of a 4-byte integer string length and a contiguous 2xn byte block of bytes encoding the characters.

Regarding your problem,

what value do you find for the handle given by LoadLibrary ? Is it a valid one i.e. was the library module found?

ALso, do a DUMPBIN /EXPORTS on the DLL listing the exported symbols to check that you are asking for the correct symbol for the routine you want to load.
0 Kudos
ratzeputz
Beginner
1,602 Views
hi again

loadlibrary does deliver a value to the hk32Lib variable. it looks like an integer value

here you have my vb.net function SendFileToSSH:

'''

''' Sends a File to a SSH Server from a local Drive Directory

'''

''' The SSH Server. It can be an Hostname or an IP Address as string

''' The Port where the SSH Connection should go through as integer

''' The Username to connect to SSH Server as string

''' The Password to connect to SSH Server as string

''' The Path where the file should be stored on the SSH Server as string

''' The filename of the file which will be stored on the SSH Server as string.

''' The full Path of the File which should be uploaded to the SSH Server. NOTE: Must be like c:\temp\file.txt

''' Any errormessage as String if anything went wrong. Otherwise Success

'''

Public Shared Function SendFileToSSH(ByVal _host As String, ByVal _port As Integer, ByVal _user As String, ByVal _passWord As String, _

ByVal _path As String, ByVal _fileName As String, ByVal _loadFromPath As String) As String

' Important: It is helpful to send the contents of the

' sftp.LastErrorText property when requesting support.

Dim sftp As New Chilkat.SFtp()

' Set some timeouts, in milliseconds:

sftp.ConnectTimeoutMs = 5000

sftp.IdleTimeoutMs = 10000

' Connect to the SSH server.

' The standard SSH port = 22

' The hostname may be a hostname or IP address.

Dim port As Long

Dim hostname As String

hostname = _host

port = _port

success = sftp.Connect(hostname, port)

If (success <> True) Then

Return (sftp.LastErrorText)

End If

' Authenticate with the SSH server. Chilkat SFTP supports

' both password-based authenication as well as public-key

' authentication. This example uses password authenication.

success = sftp.AuthenticatePw(_user, _passWord)

If (success <> True) Then

Return (sftp.LastErrorText)

End If

' After authenticating, the SFTP subsystem must be initialized:

success = sftp.InitializeSftp()

If (success <> True) Then

Return (sftp.LastErrorText)

End If

' Open a file for writing on the SSH server.

' If the file already exists, it is overwritten.

' (Specify "createNew" instead of "createTruncate" to

' prevent overwriting existing files.)

Dim handle As String

handle = sftp.OpenFile(_path & _fileName, "writeOnly", "createTruncate")

If (handle = vbNullString) Then

Return (sftp.LastErrorText)

End If

' Upload from the local file to the SSH server.

success = sftp.UploadFile(handle, _loadFromPath)

If (success <> True) Then

Return (sftp.LastErrorText)

End If

' Close the file.

success = sftp.CloseHandle(handle)

If (success <> True) Then

Return (sftp.LastErrorText)

End If

Return "success"

End Function

0 Kudos
ratzeputz
Beginner
1,602 Views
i guess your thinking, that i did not get a value from the function by calling it.

but the general problem is, that the function itself wont be found by calling GetProcAddress.

calling this function always returns 0.

i think that the main problem is, that vb.net does not make that .dll "open" to call it from outside the .net framework
0 Kudos
anthonyrichards
New Contributor III
1,602 Views
After doing a bit of reading around, I find that your VB .Net class library DLL does not export symbols, which is why you cannot find them with GetProcAddress.

I disovered this method for using your class library via a C++ wrapper library detailed here:

http://social.msdn.microsoft.com/Forums/en-US/vclanguage/thread/10754d76-e1a3-4127-89a5-2f5a6b89598d
0 Kudos
anthonyrichards
New Contributor III
1,602 Views
You could also rewrite your code using Visual Basic, in which case you can create a Windows DLL from VB as described here (using ChilKatFtp2.dll instead of ChilKatDotnet2.dll)

http://windowsdevcenter.com/pub/a/windows/2005/04/26/create_dll.html?page=1
0 Kudos
ratzeputz
Beginner
1,602 Views
thx for your answers.

wow...pretty hard stuff isnt it :)

only thing i want to do is directly using ssh connection and transfer files over sftp out of fortran *cry* and theres no easy way to handle this *cry* :)

well...i will read and search through your given links...maybe i will find any solution that works :)
0 Kudos
Arjen_Markus
Honored Contributor I
1,602 Views
Well, you are trying to do something securely (as that is the purpose of ssh and sftp) and there is nothing easy about software security.

Regards,

Arjen
0 Kudos
ratzeputz
Beginner
1,602 Views
yeah thats right but having some modules that brings the functionality with it would be a lot easier that switching between those programming languages.

but there arent some modules available so doing this way will be the only way...even if its hard :)
0 Kudos
Arjen_Markus
Honored Contributor I
1,602 Views
Hm, it might be an idea for my Flibs project (http://flibs.sf.net) - I just do not know what libraries to use
(yet). Indeed, a decent interface that can be used from a Fortran program would make this a lot more convenient.

Regards,

Arjen
0 Kudos
ratzeputz
Beginner
1,602 Views
i think that would generally be a good idea cause i am sure, that much fortran developers would wish to have a ssh connection in there programs without those "hacking" "wrapping" "switching" methods :)

youll get hero status then hehe
0 Kudos
Arjen_Markus
Honored Contributor I
1,602 Views
I won't promise anything, but a quick look at the available documentation reveals that it probably
isn't all that complicated. I will have to take a closer look and find some time ...

Regards,

Arjen
0 Kudos
anthonyrichards
New Contributor III
1,602 Views
Have you thought of exposing your VB .NET SSH code via COM interfaces in a Class Library DLL?
You can generate a type library .TLB file from the .DLL and then use the Fortran Module Wizard on the .TLB file to generate code to call the methods. It is quite straightforward as the attached code should show. As a demonstration I built the simplest Class library Dll I could imagine, which contains a single function to return the name of the class.
The VB .Net code for the application (which I called ClassLibrary1) is

Public Interface AnInterface
Function WhoAmI() As String
End Interface
Public Class Class1
Implements AnInterface
Public Function WhoAmI() As String Implements AnInterface.WhoAmI
Return "Class1"
End Function

End Class

In Visual Studio, under Application properties...assembly information.. tick the "Make assembly COM-visible" box and build the application, which creates the ClassLibrary1.DLL.
Then you must use the tool REGASM.EXE (normally found in one of the Framework folders in C:\windows\Microsoft.NET\) to both generate the type library .TLB file and register the TLB and add the DLL to the codebase using

REGASM /TLB /CODEBASE ClassLibrary1.dll

To access this class using Fortran, I created the simple console program that is attached. First though, I used the Fortran Module wizard on the ClassLibrary1.TLB file to generate the code required to handle the calls to the Class1 methods exposed to COM (the only one being WhoAmI). This generated module I called Class1Library and the code is in file Class1Library.f90. By using the CLSID and IID values given in this module, made available via the USE Class1Library statement, it is possible to create an instance of Class1 and call the 'AnInterface' method . As you should see, the code worked OK, the character string 'Class1' being returned, as desired.

All you now have to do is create a VB .NET class containing your SSH routine(s) and expose them using 'Interface' and 'Implements' statements in the VB code. After generating the Class Library .DLL, generating the TLB and registering it, then generating a Fortran Module using the Fortran Module wizard, you should be able to call your SSH functions from Fortran by using appropriate calls to the module code.

Hope this helps!

P.S. I used Visual Basic 2008 Express edition to generate the class library .DLL
0 Kudos
Arjen_Markus
Honored Contributor I
1,602 Views
I was referring to the library "libssh" that I found on the Internet - it is a (probablyhigh-level) interface
to the SSL protocol with some interesting components. A Fortran interface to that library should not be
too much work and you would get access to things like running a remote command or copying data without
too much fuss. (Right now though, I am missing a few auxiliary libraries that are use by libssh, so I could
not make progress.)

Regards,

Arjen
0 Kudos
anthonyrichards
New Contributor III
1,602 Views
My post was aimed at the original poster.
0 Kudos
Arjen_Markus
Honored Contributor I
1,602 Views
Sure, I understood that and I was replying to my own post ;). The sequential display hid that (mine was reply #16 to reply #14).

Regards,

Arjen
0 Kudos
ratzeputz
Beginner
1,482 Views
hi again.

first of all a BIG BIG thank you to anthonyrichards.
thats really a great solution and seems pretty easy to me.

but the problem that i have now is that the intel fortran module wizard always breaks with the errormessage "attempted an unsupported operatio" on step 2/2.

i am a bit unsure which members i have to select to add but i tried many ways, always with the same result that the wizard breaks with the errormessage.

any ideas?

edit:
seems to be a win7 problem.
tried it on a win xp machine and the module was created by using the .dll file
using the .tlb file also not worked.
0 Kudos
Reply