forums.silverfrost.com Forum Index forums.silverfrost.com
Welcome to the Silverfrost forums
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

VB.NET calling an FTN95 DLL

 
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> Support
View previous topic :: View next topic  
Author Message
TPSchultz



Joined: 30 Dec 2009
Posts: 9
Location: Los Angeles, USA

PostPosted: Fri Feb 12, 2010 7:16 pm    Post subject: VB.NET calling an FTN95 DLL Reply with quote

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
View user's profile Send private message
Emanuele



Joined: 21 Oct 2009
Posts: 77
Location: Bologna (Italy)

PostPosted: Mon Feb 15, 2010 5:58 pm    Post subject: Reply with quote

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
View user's profile Send private message
TPSchultz



Joined: 30 Dec 2009
Posts: 9
Location: Los Angeles, USA

PostPosted: Mon Feb 15, 2010 7:41 pm    Post subject: Reply with quote

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
View user's profile Send private message
TPSchultz



Joined: 30 Dec 2009
Posts: 9
Location: Los Angeles, USA

PostPosted: Mon Feb 22, 2010 3:31 am    Post subject: Reply with quote

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
View user's profile Send private message
TPSchultz



Joined: 30 Dec 2009
Posts: 9
Location: Los Angeles, USA

PostPosted: Mon Feb 22, 2010 7:50 am    Post subject: Reply with quote

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
View user's profile Send private message
MarzAttax



Joined: 15 Jun 2006
Posts: 46

PostPosted: Tue Jul 29, 2014 9:46 pm    Post subject: Re: Reply with quote

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
Very Happy
Back to top
View user's profile Send private message
TPSchultz



Joined: 30 Dec 2009
Posts: 9
Location: Los Angeles, USA

PostPosted: Tue Jul 29, 2014 11:52 pm    Post subject: Reply with quote

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
View user's profile Send private message
MarzAttax



Joined: 15 Jun 2006
Posts: 46

PostPosted: Wed Jul 30, 2014 12:05 am    Post subject: Reply with quote

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
View user's profile Send private message
MarzAttax



Joined: 15 Jun 2006
Posts: 46

PostPosted: Wed Jul 30, 2014 1:22 am    Post subject: Reply with quote

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
View user's profile Send private message
MarzAttax



Joined: 15 Jun 2006
Posts: 46

PostPosted: Wed Jul 30, 2014 2:00 am    Post subject: Reply with quote

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
View user's profile Send private message
MarzAttax



Joined: 15 Jun 2006
Posts: 46

PostPosted: Wed Jul 30, 2014 2:54 am    Post subject: Reply with quote

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
View user's profile Send private message
MarzAttax



Joined: 15 Jun 2006
Posts: 46

PostPosted: Wed Jul 30, 2014 3:00 am    Post subject: Reply with quote

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
View user's profile Send private message
TPSchultz



Joined: 30 Dec 2009
Posts: 9
Location: Los Angeles, USA

PostPosted: Wed Jul 30, 2014 5:31 am    Post subject: Reply with quote

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
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> Support All times are GMT + 1 Hour
Page 1 of 1

 
Jump to:  
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