- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Try terminating all the string arguments with CHAR(0) and see if that works. Visual Basic expects and delivers null-terminated strings.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
'''
'''
'''
'''
'''
'''
'''
'''
'''
'''
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
http://windowsdevcenter.com/pub/a/windows/2005/04/26/create_dll.html?page=1
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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 :)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Regards,
Arjen
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
but there arent some modules available so doing this way will be the only way...even if its hard :)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
(yet). Indeed, a decent interface that can be used from a Fortran program would make this a lot more convenient.
Regards,
Arjen
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
youll get hero status then hehe
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
isn't all that complicated. I will have to take a closer look and find some time ...
Regards,
Arjen
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Regards,
Arjen
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Public Interface AnInterface
Function
WhoAmI() As String
Function
SendFileToSSH(ByVal a_host As String, ByVal a_port As Integer, ByVal a_user
As String, ByVal a_passWord As String, _
ByVal
a_path As String,
ByVal a_fileName As
String, ByVal
a_loa...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page