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

Linking CVF 6 dll to CVF project

clintksu
Beginner
1,081 Views
I am trying to link an existing user-created dll to another CVF 6 project so that I can call the functions within this dll. I have the .lib file and the dll.

Steps taken:
1. I have added the library file into the Object/Library Modules (Project->Settings->Linking Tab->Object/Library Modules->GasPropsDLL2010-3.lib)

2. Added the directory path for both the dll and the .lib file (Tools->Options->Directories Tab-> added .lib path into library and dll path to executables

3. Added .lib file and dllinto project files, they were put into the resource folder when added (Project->Add to Project->Files)


Then, within the code I have to call a function (within the dll)that calculates the saturation pressure as a function of temp (I am positive that the dll function name is correct):

SUBROUTINE PSAT_S(T,PR)

!DEC$ ATTRIBUTES DLLIMPORT :: PSAT_F

IMPLICIT DOUBLE PRECISION (A-H,O-Z)

PR=0.0d0

T=341.0D0

PR= PSAT_F(T)

RETURN

END


After implementing these steps, I am still receiving the following errors:

error LNK2001: unresolved external symbol _PSAT_F@4

Debug/TRECS.exe : fatal error LNK1120: 1 unresolved externals


With all of this in mind, I was wondering if I am missing a step to link the dll to my project or if I am even following the correct procedure. To me, it seems thatCVF is still not finding the dll.Can someone please let me know the correct procedure/method for doing this?

Thanks

0 Kudos
9 Replies
DavidWhite
Valued Contributor II
1,081 Views
Try running dumpbin /EXPORTS against your DLL to check which symbols have been exported to see whether they match what you are trying to use (_PSAT_F@4). the exported symbols may be in lower case or have different number or size of arguments.

David
0 Kudos
clintksu
Beginner
1,081 Views
David,

I used the dumpbin /EXPORTS to view the functions within the dll. Also, I have the dll linked to an excel spreadsheet ( which is working.) Declaring the functions VB looks like:

"Private Declare Function PSAT_F Lib "C:\...\gaspropsDLL2010-3.DLL" (T As Double) As Double"


So the function name is all caps PSAT_F and the argument it recieves is a double.

I guess I'm not sure if the procedure I used in the previous post is the correct way to link a dll to another CVF project or if there is an easier way to do so.

Does anyone know how to link an existing cvf dll to another cvf project?

Thank you,

Clint
0 Kudos
mecej4
Honored Contributor III
1,081 Views
You have a mismatch between the two languages' default types/calling conventions. By default, Fortran calls by reference (address). That is why PSAT_F is decorated to PSAT_F@4 -- the 32-bit address of the argument T is 4 bytes long. On the other hand, your Basic function is told that the argument is the value of T, which is 8 bytes long.
0 Kudos
clintksu
Beginner
1,081 Views

Thank you for the response. When I referred to VB, I meant VBA. The calling convention on VBA is ByRef. Am i referencing the DLLIMPORT statement correctly? This is the first time i have used that statement to import a FORTRAN-created DLL function into another FORTRAN program. It seems i missing a small detail in the DEC statement.

Again, thank you for the help.

0 Kudos
clintksu
Beginner
1,081 Views

Hello all,

I have determined why I wasn't able to call the functions within the dll (very simple error.) In order to import the dll function, the following import coding must be used:

!DEC$ ATTRIBUTES DLLIMPORT:: PSAT_F
!DEC$ ATTRIBUTES ALIAS:"PSAT_F" :: PSAT_F

I'm not sure if the procedure followed in my first post had much influence on linking the dll to the exe (I will investigate what needs to be done), but adding this code fixed the problem.

Thank you all for your help and support,

Clint

0 Kudos
abhimodak
New Contributor I
1,081 Views
Hi Clint

Good that you get it working.

It appear a bit confusing to me, however. Are you sure that you don't have the ALIAS in the corresponding DLLEXPORT as well? The CVF calling convention is STDCALL + UpperCase. On Win32 leading underscore is also added. STDCALL adds @bytes. Thus, as David said, if the dll was created with CVF convention then subroutine name would appear as _PSAT_F@4 in the dependency walker. Consequently, if the program unit having DLLIMPORT also uses the same convention there should be no problem.

Does the dependency walker (or dumpbin /exports) show you BOTH _PSAT_F@4 and PSAT_F?

Abhi

p.s. May be I am wrong, but based on how I use fortran dll in VB, I also think that the VBA application looks for PSAT_F (without any decorations). If it loads correctly then the your dll must be exporting PSAT_F and not _PSAT_F@4.

0 Kudos
clintksu
Beginner
1,081 Views

Hi Abhi,

When I looked at Dependency Walker, I only had PSAT_F not _PSAT_F@4.

I'm pretty new to importing/exporting dll's, but the exporting statementused is as follows:

!DEC$ ATTRIBUTES DLLEXPORT ::PSAT_F
!DEC$ ATTRIBUTES ALIAS:"PSAT_F" :: PSAT_F

and the importing statement that I found to work is:

!DEC$ ATTRIBUTES DLLIMPORT:: PSAT_F

!DEC$ ATTRIBUTES ALIAS:"PSAT_F" :: PSAT_F


Maybe I'm wrong but I'mguessing that my original import call statement (only !DEC$ ATTRIBUTES DLLEXPORT :: PSAT_F, shownin my first post) assumes that STDCALL was used and assigns the function to _PSAT_F@4, which the compiler cannot find in the dll.


Clint

0 Kudos
Steven_L_Intel1
Employee
1,081 Views
CVF uses STDCALL by default. DLLEXPORT/DLLIMPORT doesn't change that.
0 Kudos
abhimodak
New Contributor I
1,081 Views
Hi Clint

Thanks for confirming that you had ALIAS in the DLLEXPORT as well. Now it makes sense.

As Steve mentioned, the STDCALL itself won't change (unless you override it using ATTRIBUTES). If you comment out the ALIAS in your export your dll would show _PSAT_F@4 in the dependency walker. (In that case, your VBA would also fail to load the function.) With ALIAS you have specifically told what name should be used and hence PSAT_F appears in the d-walker. If you change it to --- ALIAS: 'SOMETHINGELSE' --- SOMETHINGELSE will appear.

Consequently, you must also add the ALIAS in your DLLIMPORT. Without ALIAS, your calling program is looking for _PSAT_F@4 as per the CVF convention. With ALIAS it will look for just PSAT_F.

Abhi
0 Kudos
Reply