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

Calling Visual Basic code from Fortran - Anyone?

egil_giertsen
Beginner
2,213 Views

Hi,

I'veended up with a set of formulas originally coded in Visual Basic, that I now need to call from Fortran.

Anyone tried that?

Thanks in advance for any help...

Best regards,

8-) Egil

Egil Giertsen
Senior Research Scientist
Phone : +47 7359 2081
Telefax: +47 7359 2660
Mobile : +47 9305 8672
_____________________________
MARINTEK SINTEF GROUP
Department of Structural Engineering
Otto Nielsens vei 10
P O Box 4125, Valentinlyst
N-7450 Trondheim
NORWAY
_____________________________
http://www.marintek.sintef.no

0 Kudos
37 Replies
Steven_L_Intel1
Employee
1,426 Views
That direction is a lot of work. What version of VB are you using? (And what version of Fortran?) I think the way you have to do it is create a .NET assembly in VB and use the Intel Fortran Module Wizard to create interfaces for it, but this is not sonething I have tried.

It might be a lot simpler to translate the function code to Fortran.
0 Kudos
egil_giertsen
Beginner
1,426 Views

Steve, thanks for getting back to me on this.

Currently, I use quite old versions of Fortran (CVF v6.6) and VB (v6.0).

Hhmm, was a bit afraid about getting the "a lot of work" answer. I have thought about calling the VB code wrapped in a VB DLL from C/C++, and then call the C/C++ vrapper code from Fortran. I'm not sure, but I believe that might work. Any immediate thoughts?

I have also thought about recoding all formulas from VB to Fortran. Does anyone know about a VB to Fortran code translator? Not many of those I guess...

Egil

0 Kudos
Steven_L_Intel1
Employee
1,426 Views
If you're using VB6, it may be less work. You should be able to call a VB6 DLL from CVF as long as you get the calling sequence right.
0 Kudos
egil_giertsen
Beginner
1,426 Views

Steve,

I had a go at it, with the following test code:

VB (ActiveX DLL):
-------
Public Sub VBROUTINE(iop As Long)
iop = 5
End Sub
-------

Fortran (Console Application):
-------
program test
INTERFACE
SUBROUTINE vbroutine (iop)
!DEC$ ATTRIBUTES DLLIMPORT :: vbroutine
!DEC$ ATTRIBUTES ALIAS: '_VBROUTINE@4' :: vbroutine
INTEGER iop
END SUBROUTINE vbroutine
END INTERFACE
integer icode
icode = 0
CALL vbroutine (icode)
print*,'icode = ',icode
END
-------

I've added the VB generated DLL as a file to the project.

The CVF linker fails with the following message:
--------------------Configuration: CallingVBfromFortran - Win32 Debug--------------------
Linking...
CallingVBfromFortran.obj : error LNK2001: unresolved external symbol _VBROUTINE@4
Debug/CallingVBfromFortran.exe : fatal error LNK1120: 1 unresolved externals
Error executing link.exe.
CallingVBfromFortran.exe - 2 error(s), 0 warning(s)

Hence, it is note able to get hold of the VB routine from the DLL.

Any idea?

Thanks in advance...

Egil

0 Kudos
Steven_L_Intel1
Employee
1,426 Views
VB does not "decorate" its names. You'll have to analyze the DLL to see what name it has chosen. Dependency Walker is good for this.
0 Kudos
tashker__michael
Beginner
1,426 Views

Wait a minute, wait a minute. Unless I'm sadly and massively mistaken, you can't call VB DLL code like that. VB6 can only generate activex DLLs, not 'regular' DLLs like c/c++ or fortran. And an activeX DLL has to be instantiated as an object. If you were doing the calling in VB, it would be something like

dim something as object

set something=createobject("x.y")

where x and y were defined by the internals of the ActiveX. (Please ignore my bad memory of the syntax of creating ActiveX objects from vb, but the principle is correct.)Now you can't just do that in fortran with the syntax of using a normal DLL (i.e. an interface and a call). You've got to go the whole COM route, which is nasty stuff even in c++. You've got to initialize COM, something like ::CoInitialize(NULL); and on and on.

My current level of knowledge tells me there's no simple way: it's a long hard slog.

0 Kudos
egil_giertsen
Beginner
1,426 Views

Yes, I've found out that you are basically right - but fortunately there is a workaround. After some searching I came across the following - quite great - article:
http://www.windowsdevcenter.com/pub/a/windows/2005/04/26/create_dll.html

Check it out - I've tested it from VB - works like a charm...

I will now try it out from Fortran.

Egil

0 Kudos
egil_giertsen
Beginner
1,426 Views

Hi again!

As I mentioned in my previous post, I've managed to make a VB DLL, and to test it from a VB application. However, how do I make the proper reference to the DLL routines during linking, to avoid getting unresolved externals?

--------------------Configuration: CallingVBfromFortran - Win32 Debug--------------------
Linking...
CallingVBfromFortran.obj : error LNK2001: unresolved external symbol _SQUAREUC@4
Debug/CallingVBfromFortran.exe : fatal error LNK1120: 1 unresolved externals
Error executing link.exe.
CallingVBfromFortran.exe - 2 error(s), 0 warning(s)

Thanks for any help...

Egil

0 Kudos
Steven_L_Intel1
Employee
1,426 Views
See my previous post.
0 Kudos
g_f_thomas
Beginner
1,426 Views

I wouldn't go that far. This secondary rehash is a vulgarization of John Chamberlain's article (+ VB addin) titled 'Compile Controller' that appeared in VBPJ in Nov 1999.

Check it out. I've been calling VB from Fortran since DVF days.

Gerry

0 Kudos
tashker__michael
Beginner
1,426 Views

I salute those who have created regular DLLs from VB... an impressive piece of work. I stand corrected, mind blown. I have googled for Chamberlain's article, finding only references, no actual text. Can anyone produce a valid link, or upload it?

0 Kudos
g_f_thomas
Beginner
1,426 Views
0 Kudos
egil_giertsen
Beginner
1,426 Views

Hi again,

Sorry about this, but I'm still struggling with getting the naming of the routines in my Fortran INTERFACE block to match the exported routine in my Visual Basic (VB) generated DLL.

When using DependencyWalker on the VB generated DLL, the exported names seems to be straightforward and as expected. I've then added the .lib file generated together with the DLL to my Fortran project, but when linking the Fortran test program the routines which shouldbe inthe VB DLL are reported asundefined.

Using the same approach with a Fortran generated DLL works fine.

Am I missing something obvious? Any help is deeply appreciated...

What is the best way of inspecting the .lib file generated with a DLL?

Thanks,
Egil

0 Kudos
anthonyrichards
New Contributor III
1,426 Views

For more help, you must list here a)the EXACT names of the routines EXPORTed by your DLL, and b) list yourFortran DLLIMPORT and other compiler directives in your Fortran INTERFACE blocks for the routines you wish to import.

Use DUMPBIN to get a list of EXPORTS

0 Kudos
anthonyrichards
New Contributor III
1,426 Views

(please delete, multiple post )

0 Kudos
egil_giertsen
Beginner
1,426 Views

Hi,

DUMPBIN /EXPORTS on my VB DLL gives the following output:

============
Microsoft COFF Binary File Dumper Version 6.00.8447
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.


Dump of file MathDLL.dll

File Type: DLL

Section contains the following exports for MathDLL.dll

0 characteristics
468CAAB3 time date stamp Thu Jul 05 10:24:19 2007
0.00 version
1 ordinal base
9 number of functions
9 number of names

ordinal hint RVA name

1 0 00001AF0 Decrement
6 1 00001966 DllCanUnloadNow
7 2 0000193A DllGetClassObject
2 3 00001990 DllMain
8 4 00001950 DllRegisterServer
9 5 00001924 DllUnregisterServer
3 6 000019B0 Increment
5 7 00001C30 Square
4 8 00001D90 Square2

Summary

1000 .data
1000 .reloc
1000 .rsrc
2000 .text
============

My Fortran test program source code is as follows:

============
program test

INTERFACE
SUBROUTINE Square2 (ivar1)
!DEC$ ATTRIBUTES DLLIMPORT :: Square2
!DEC$ ATTRIBUTES ALIAS : '_SQUARE2@4' :: Square2
integer ivar1
END SUBROUTINE Square2
END INTERFACE

INTERFACE
SUBROUTINE FortranDLL (ivar2, rvar2)
!DEC$ ATTRIBUTES DLLIMPORT :: FortranDLL
!DEC$ ATTRIBUTES ALIAS : 'FortranDLL' :: FortranDLL
integer ivar2
double precision rvar2
END
END INTERFACE

integer nmb

integer i1
double precision r1

nmb = 4

print*,'Before Square: nmb = ',nmb
call Square2 (nmb)
print*,'After Square: nmb = ',nmb

i1 = 4
r1 = 3.14159e2

print*,'Before FortranDLL'
call FortranDLL (i1, r1)
print*,'After FortranDLL'

pause

END
============

During linking I get the following error message:
CallingVBfromFortran.obj : error LNK2001: unresolved external symbol _SQUARE2@4

As you can see I've tried to add alias definition to the INTERFACE, without success.

Thanks,

Egil

0 Kudos
Steven_L_Intel1
Employee
1,426 Views
Not surprising - as shown in the output you posted, the name of the routine in the DLL is "Square2", not _SQUARE2@4". VB does not apply the usual STDCALL decoration rules.
0 Kudos
g_f_thomas
Beginner
1,426 Views

You now have a VB DLL with unmangled exports, except for FortranDLL. You don't need to use !DEC$ metacommands in writing the interfaces. See the IVF Samples on how to access a classic DLL, as is your VB DLL,from C/Fortran/VB. You'll need to use the Win API to load the, resolve its exports, and free the DLL when you're done.

Gerry

0 Kudos
norm
Beginner
1,426 Views

Steve,

This Wizard sounds exciting.

Please try to create a simple sample of Fortran using VB.NET or C#, for I have the follwoing issue in Visual Studio 2005.

The issue seems to be simple to define:

1. Visual Studio VB and C# projects can use other VB and C# projects.

2. Visual Studio VB and C# projects can use other FORTRAN projects.

3. Visual Studio FORTRAN projects can use other FORTRAN projects.

4. Visual Studio FORTRAN projects cannot use other VB and C# projects.

Was this an oversight? Will th Wizard fix it?

Thanks,

Norm

0 Kudos
Steven_L_Intel1
Employee
1,341 Views
The Module Wizard handles your item #4. It is not an oversight. I'll try to work up an example, though I'm not experienced at VB or C#.
0 Kudos
Reply