|
forums.silverfrost.com Welcome to the Silverfrost forums
|
View previous topic :: View next topic |
Author |
Message |
TPSchultz
Joined: 30 Dec 2009 Posts: 9 Location: Los Angeles, USA
|
Posted: Fri Feb 12, 2010 7:16 pm Post subject: VB.NET calling an FTN95 DLL |
|
|
I've got some old (originally Fortran 77) subroutines that I've converted into a DLL that I am calling from Visual Basic 2008.NET SP1. I pass it several variables (some integers, floating points and one string) and it passes back an answer in one of the floating points and the string.
When I run the VB.NET application, either in the Visual Studio IDE or as a compiled executable, I sometimes encounter an error of "ArithmeticException was unhandled" with a detail of "Overflow or underflow in the arithmetic operation." This error coincides with the call to the DLL. The odd part is that if I simply hit continue, the DLL returns the correct results.
Although not 100% consistent, it seems to happen mostly when one of the variables happens to be negative. In playing around, if I eliminate the string variable, I can't seem to make it crash. If I add three more dummy string variables, it doesn't crash. I've even tried passing back some arrays to see what was going on inside the DLL... adding three of them also seems to be successful.
Again, the odd part is that when it does error out, it always gives me back the correct answer on a second (re)try. To me, this seems like some sort of memory allocation issue and adding more variables to the call is simply shifting stuff around in memory and masking an underlying problem.
From VB.NET, all the numeric variables are passed ByRef and the string is passed ByVal (arrays were also passed ByVal)... it won't work any other way. I've checked to make certain the variables match in type in both Fortran and VB code... INTEGERs are Integers in VB (and I've tried declaring them as Short too, just to see) and REALs are Single in VB.
Anybody have any ideas as to what may be happening?
Tim |
|
Back to top |
|
|
Emanuele
Joined: 21 Oct 2009 Posts: 77 Location: Bologna (Italy)
|
Posted: Mon Feb 15, 2010 5:58 pm Post subject: |
|
|
It's hard to answer without looking at the code. Firstly, did you declare the intent in fortran for the variables passed by VB (I mean intent=in in case of byVal and intent=out or inout in case of byRef)?
Secondly, if you declare the fortran reals as VB doubles, did you get the same error? Finally, how is the VB string declared in your fortran?
Emanuele |
|
Back to top |
|
|
TPSchultz
Joined: 30 Dec 2009 Posts: 9 Location: Los Angeles, USA
|
Posted: Mon Feb 15, 2010 7:41 pm Post subject: |
|
|
Originally being Fortran 77 code, the Intent attribute wasn't used, and not be overly experienced in Fortran, I had never heard of if. However, at your suggestion, I just tried it... it made no difference.
The string is simply declared as: character flag*2 (I also just tried it as character, intent(out):: flag*2, but it made no difference).
Declaring the floating point variables as Doubles in VB produced garbage, as the number of bytes passed didn't line up (Fortran thought I was passing zero values).
In case I wasn't as clear as I could have been, using the same list of variables in testing each and every time, sometimes it'll make it through without this error, sometimes it doesn't. But once I hit the error and retry, from then on I can't make the Call fail until I stop the application and restart it. Very odd behaviour.
Thanks for the ideas. |
|
Back to top |
|
|
TPSchultz
Joined: 30 Dec 2009 Posts: 9 Location: Los Angeles, USA
|
Posted: Mon Feb 22, 2010 3:31 am Post subject: |
|
|
I had been compiling the DLL in Win32 mode, so I tried to switch to .NET mode since I am trying to call this from Visual Basic.NET. However, when I switch the FTN95 compiler/linker options to .NET DLL mode, my VB.NET application now says it can't find the DLL entry points.
I tried giving the subroutines an ASSEMBLY_INTERFACE name, but it didn't make a difference, and I don't see an option for ExportAll, like in the Win32 mode.
I, obviously, am missing something, either in the compiler/linker options or perhaps in the calling program options. Any suggestions would be appreciated. |
|
Back to top |
|
|
TPSchultz
Joined: 30 Dec 2009 Posts: 9 Location: Los Angeles, USA
|
Posted: Mon Feb 22, 2010 7:50 am Post subject: |
|
|
I figured out how to bring in the .NET dll and add a reference to it in the VB.NET project. So far, so good.
Tim |
|
Back to top |
|
|
MarzAttax
Joined: 15 Jun 2006 Posts: 46
|
Posted: Tue Jul 29, 2014 9:46 pm Post subject: Re: |
|
|
TPSchultz wrote: | I figured out how to bring in the .NET dll and add a reference to it in the VB.NET project. So far, so good.
Tim |
I am having similar troubles.
My code is in a single file and has five subprograms (Function-name_1, Function-name_2, etc) each having an "ASSEMBLY_INTERFACE"
If I build the Fortran with "Debug.NET" it produces three files:
1) Filename.dll
2) Filename.pdb
3) Function-name_1.dbk
When adding Filename.dll as a reference to my VB.NET project, I get the "cannot find an entry point" malarkey.
I've tried various combinations of "ALIAS" UPPERCASE, lowercase etc all to no avail.
If I build the Fortran with "Release.NET" I get the following:
"LINK : error : File not found: export.dll"
I used "dllexp.exe" (a dll export viewer) to examine Filename.dll and it shows nothing.
It would be nice to know how you got it to work.
Help please.
Marz
|
|
Back to top |
|
|
TPSchultz
Joined: 30 Dec 2009 Posts: 9 Location: Los Angeles, USA
|
Posted: Tue Jul 29, 2014 11:52 pm Post subject: |
|
|
Well, it's been years since I posted this and made it work; I ultimately dropped trying to reuse old Fortran code and spent the time to convert everything to VB (things worked in VB2008, but I couldn't get the same code to run reliably in VB2010, so I gave up).
However, I went back and think I remember what I did. For a .NET DLL, for each sub or function, you need to give a unique name to the Assembly_Interface name; you cannot use the same name as the sub or function itself, such as:
Code: |
REAL FUNCTION ffunc (y)
REAL, Intent(inout):: y
Assembly_Interface(name="My_FFUNC")
ffunc = y + 1.23
END
|
In VB.Net, add a reference in the project properties to where the compiled FTN95 dll resides. Add an Imports statement to the top of the form with the proper name from your added reference file.
At this point, call the function like any other .NET function:
Code: |
Dim y As Single
y = 3
MsgBox(My_FFUNC(y)) ' Display the results.
|
I don't believe I can be of any further assistance. Good Luck. |
|
Back to top |
|
|
MarzAttax
Joined: 15 Jun 2006 Posts: 46
|
Posted: Wed Jul 30, 2014 12:05 am Post subject: |
|
|
Hi there, thanks for getting back to me.
I've done everything apart from the Imports bit. I don't understand what you mean by "proper name from your added reference file" sorry.
Let's say the DLL filename is: FilenameDLL.dll
and
a subroutine in it is Ferret(n1, Xs, Ys, V1s, V2s, V3s, n2) that has:
Integer*4, INTENT(IN) :: n1
Real*4, INTENT(INOUT) :: Xs(:), Ys(:)
Integer*4, INTENT(OUT) :: V1s(:), V2s(:), V3s(:)
Integer*4, INTENT(OUT) :: n2
ASSEMBLY_INTERFACE(NAME="MyFerret")
I have decalred the following in VB.NET:
Public Declare Sub VB_Func Lib "FilenameDLL.dll" Alias "MYFERRET" _
(ByVal n1 As Integer, _
ByVal Xs() As Single, ByVal Ys() As Single, _
ByRef V1s() As Integer, ByRef V2s() As Integer, ByRef V3s() As Integer, _
ByRef n2 As Integer)
I have:
Dim aL as Integer, nL as Integer
Dim XsL() As Single, YsL() As Single, ZsL() As Single
Dim V1sL() As Integer, V2sL() As Integer, V3sL() As Integer
...some faffing about ....
and I call as:
VB_Func(aL, XsL, YsL, V1sL, V2sL, V3sL, nL)
what is "the proper name for the Imports statement"?
I've tried "Imports FilenameDLL" and I get:
"Unable to find an entry point named 'MYFERRET' in DLL FilenameDLL.dll'"
I read somewhere (on web) that the Alias ought to be ALL uppercase, but I tried it in the form given in the Fortran code, namely "MyFerret". This doesn't work either.
However, if I comment out the "Public Declare", the VB-IDE shows me "Error 1 'Ferret' has a return type that is not supported or parameter types that are not supported."
Looks like this may be the problem.
Thanks again
Marz
Last edited by MarzAttax on Wed Jul 30, 2014 1:36 am; edited 5 times in total |
|
Back to top |
|
|
MarzAttax
Joined: 15 Jun 2006 Posts: 46
|
Posted: Wed Jul 30, 2014 1:22 am Post subject: |
|
|
Further, since the Plato IDE showed me that:
"Assembly file ..............\FilenmeDLL.dll for .NET 2.0 produced"
I changed the "Target Framework" in the VB Project Properties to:
".NET Framework 2.0"
and subsequently got lots of warnings in the VB Project "UseFortramDLL"
"Warning 1 The primary reference "System.Core", which is a framework assembly, could not be resolved in the currently targeted framework. ".NETFramework,Version=v2.0". To resolve this problem, either remove the reference "System.Core" or retarget your application to a framework version which contains "System.Core". UseFortranDLL"
"Warning 3 The primary reference "System.Data.DataSetExtensions" could not be resolved because it has an indirect dependency on the framework assembly "System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" which could not be resolved in the currently targeted framework. ".NETFramework,Version=v2.0". To resolve this problem, either remove the reference "System.Data.DataSetExtensions" or retarget your application to a framework version which contains "System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089". UseFortranDLL"
"Warning 5 The primary reference "System.Data.DataSetExtensions", which is a framework assembly, could not be resolved in the currently targeted framework. ".NETFramework,Version=v2.0". To resolve this problem, either remove the reference "System.Data.DataSetExtensions" or retarget your application to a framework version which contains "System.Data.DataSetExtensions". UseFortranDLL"
"Warning 2 The primary reference "System.Xml.Linq" could not be resolved because it has an indirect dependency on the framework assembly "System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" which could not be resolved in the currently targeted framework. ".NETFramework,Version=v2.0". To resolve this problem, either remove the reference "System.Xml.Linq" or retarget your application to a framework version which contains "System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089". UseFortranDLL"
"Warning 4 The primary reference "System.Xml.Linq", which is a framework assembly, could not be resolved in the currently targeted framework. ".NETFramework,Version=v2.0". To resolve this problem, either remove the reference "System.Xml.Linq" or retarget your application to a framework version which contains "System.Xml.Linq". UseFortranDLL"
"Warning 6 The referenced component 'System.Core' could not be found. "
"Warning 8 The referenced component 'System.Data.DataSetExtensions' could not be found. "
"Warning 7 The referenced component 'System.Xml.Linq' could not be found. "
Confused much!
Marz |
|
Back to top |
|
|
MarzAttax
Joined: 15 Jun 2006 Posts: 46
|
Posted: Wed Jul 30, 2014 2:00 am Post subject: |
|
|
I've even tried the following from a Google search (NAG header file)
Imports System.Runtime.InteropServices
Public Class Form1
Public Declare Sub VbFerret Lib "DelaunayDll.dll" Alias "MYFERRET" _
(ByVal n1P As Integer, _
<[In]()> ByVal Xs() As Single, _
<[In]()> ByVal Ys() As Single, _
<Out()> ByVal V1s() As Integer, _
<Out()> ByVal V2s() As Integer, _
<Out()> ByVal V3() As Integer, _
ByRef n2P As Integer)
.....so now I am definitely in the realms of not knowing anything that I am doing - lol |
|
Back to top |
|
|
MarzAttax
Joined: 15 Jun 2006 Posts: 46
|
Posted: Wed Jul 30, 2014 2:54 am Post subject: |
|
|
Just tried this:
Public Declare Sub VbFerret Lib "FilenameDLLdll" Alias "MYFERRET" _
(ByVal n1 As Integer, _
ByVal Xs As Single, _
ByVal Ys As Single, _
ByVal V1s As Integer, _
ByVal V2s As Integer, _
ByVal V3 As Integer, _
ByRef n2 As Integer)
with
VbFerret(aL, XsL(0), YsL(0), V1sL(0), V2sL(0), V3sL(0), nL)
Still unable to find entry point ....... |
|
Back to top |
|
|
MarzAttax
Joined: 15 Jun 2006 Posts: 46
|
Posted: Wed Jul 30, 2014 3:00 am Post subject: |
|
|
Think I got it sussed now.
I right-clicked on the "FilenameDLL" of "Imports FilenameDLL" and clicked on
"Go To Definition" to see the form of the subprograms that VB.NET was anticipating.
Seems that I merely needed to call MyFerret(....)
lol |
|
Back to top |
|
|
TPSchultz
Joined: 30 Dec 2009 Posts: 9 Location: Los Angeles, USA
|
Posted: Wed Jul 30, 2014 5:31 am Post subject: |
|
|
I'm glad you got it to work.
I just want to comment that it seems like you were confused about the differences between a Win32 DLL and a .NET DLL. In .NET, you don't need to include all of the Declare statements, you simply call the function/sub after adding the DLL reference to the project. That's why your program and the external reader utility couldn't find the entrance points - that's how a standard Win32 DLL works, not a .NET DLL. |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|