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

error LNK2019: unresolved external symbol _GETENV@16 referenced in function _OPENFL

Wagner__Urs
Novice
2,324 Views

Hello

My application is using STDCALL references.

How must I fix the upper error?

1>SETUP.obj : error LNK2019: unresolved external symbol _GETENV@16 referenced in function _OPENFL
1>Debug/KRXPC.exe : fatal error LNK1120: 1 unresolved externals

 

I am using

USE IFPORT

and LIBIFPORT.LIB

as additional libraries.

 

Thanks.

0 Kudos
22 Replies
jimdempseyatthecove
Honored Contributor III
2,118 Views

Try:

use IFPORT
character*40 libname
CALL GETENV ("LIB",libname)
TYPE *, "The LIB variable points to ",libname

Jim Dempsey

0 Kudos
Steve_Lionel
Honored Contributor III
2,112 Views

There is also the standard Fortran intrinsic procedure GET_ENVIRONMENT_VARIABLE, which I recommend instead of GETENV.

call GET_ENVIRONMENT_VARIABLE('envname',stringvar)
0 Kudos
Wagner__Urs
Novice
2,087 Views

Thanks this works fine.

But I get the next problem:

This statement crashes with an access violation

read (nread,*,err=102) psTrd(i),psPrd(i) !Reducing parameters

This source is bought and tested code. I have integrated it into my app.

i is equal 1.

How can I find out the reason of this crashes?

 

0 Kudos
Mark_Lewy
Valued Contributor I
2,081 Views

Have you tried running this with the debugger in Visual Studio?

0 Kudos
Wagner__Urs
Novice
2,077 Views

Yes there is only an access violation exception window.

0 Kudos
Mark_Lewy
Valued Contributor I
2,071 Views

OK, without seeing the declarations for nread, psTrd & psPrd it is difficult to speculate further as to why this causes an access violation.  Can you produce a small reproducer and post the code here?

0 Kudos
andrew_4619
Honored Contributor II
2,062 Views

well the value of i compared to the allowable range of the arrays psTrd(i) and psPrd(i) is the obvious one to look at.

you just need you debug the code to see values or add write statements for i.

0 Kudos
jimdempseyatthecove
Honored Contributor III
2,044 Views

Run with runtime checks /warn:all /check:bounds

 

potentially psTrd and/or psPrd are:

1) allocatable but not allocated

2) allocated but with index (i) out of bounds

3) undefined (e.g. you are not using IMPLICIT NONE and they are assumed to be undefined REALs)

4) these are dummy arguments that represent invalid or missing arguments on CALL

 

Jim Dempsey

0 Kudos
Wagner__Urs
Novice
2,007 Views

Thank You

I try to use a stand alone with the fortran code.

This works better, no access violations.

In my app I would like to run SYSTEMQQ.

I think I am using the wrong subroutine because of this

Severity Code Description Project File Line Suppression State
Error error LNK2019: unresolved external symbol _systemqq@8 referenced in function _MAIN__ Main.obj

0 Kudos
Mark_Lewy
Valued Contributor I
2,003 Views

Have you got a "use ifport" statement in your program to provide the interface to systemqq?

See, https://www.intel.com/content/www/us/en/develop/documentation/fortran-compiler-oneapi-dev-guide-and-reference/top/language-reference/a-to-z-reference/s-1/systemqq.html

 

Also, consider using the standard Fortran intrinsic procedure execute_command_line instead.

0 Kudos
mecej4
Honored Contributor III
1,990 Views

Mark_Lewy responded with the correct diagnosis. However, I noticed in your posts that you are adopting a style that makes it overly difficult for someone to diagnose the error reports. There are missing details (source code, at least the declarations and the failing subroutine calls, compiler options used), and an implicit assumption that the reader has read all your previous posts and noted their relation to the present post, and so on.

Here are a couple of suggestions. It is good that you have chosen to work with a stand-alone short program as a first step, since it reduces the complexity of the situation. Along the same lines, work on this program with the default calling convention instead of the STDCALL convention.

Here is an explanation of why the linker error LNK2019 occurred. You did not (as Mark_Lewy guessed) have a USE IFPORT line in your code, so an implicit interface was used for SYSTEMQQ. That interface is wrong, for at least two reasons.

  • The first is that the implicit type for a function name that starts with 'S' is real, whereas SYSTEMQQ returns a LOGICAL value. 
  • The compiler library does not contain a STDCALL version of SYSTEMQQ. It contains only a version that uses the Intel Fortran default calling convention. That information was not available to the compiler without the USE statement. 

Compilation and linking errors are more timely and easier to resolve than runtime errors.

0 Kudos
Wagner__Urs
Novice
1,987 Views

Thank You for Your explanation., it helps.

Yes I know I jump from one idea to another.

 

0 Kudos
Wagner__Urs
Novice
1,973 Views

This is declaration of the routine from the provider

c
subroutine REFPROPdll (hFld,hIn,hOut,iUnits,iMass,iFlag,a,b,z,
& Output,hUnits,iUCode,x,y,x3,q,ierr,herr)
c
c This new routine (Sept. 2017) makes possible the ability to obtain all
c properties in the Refprop program given two inputs from the following
c variables: T, P, D, E, H, S, and Q. The routine is documented in
c the PROP_SUB.FOR file at the top. Basically, the fluid or mixture
c names are sent in hFLd, the inputs are sent in hIn as a string
c (e.g., 'PH', 'TS', 'PQ'), the desired output is sent in hOut (e.g.,
c 'Cv', 'W', 'CSAT'), a flag for the desired units is sent in
c iUnits, a flag to specify if the compositions are mass or molar
c is sent in iFlg, the two inputs (T, P, etc.) are sent in the variables
c a and b, and the molar or mass composition is sent in z. The output
c is sent back in the Output array, a unit string is sent in hUnits,
c and the liquid and vapor compositions for two-phase states are sent
c back in x and y (along with the quality q).

include 'CONSTS.INC'
character, intent(in) :: hFld*10000, hIn*255, hOut*255
integer, intent(in) :: iUnits, iMass, iFlag
double precision, intent(in) :: a, b
double precision, intent(inout) :: z(ncmax)
double precision, intent(out) :: Output(iPropMax)
character, intent(out) :: hUnits*255
integer, intent(out) :: iUCode
double precision, intent(out) :: x(ncmax), y(ncmax), x3(ncmax), q
integer, intent(out) :: ierr
character, intent(out) :: herr*255
character hFld2*10000, hIn2*255, hOut2*255
cDEC$ ATTRIBUTES DLLEXPORT, Decorate, Alias: "REFPROPdll"::REFPROPdll
cDEC$ ATTRIBUTES STDCALL, REFERENCE::REFPROPdll
c dll_export REFPROPdll

 

In the DLL two routines are defined

_REFPROPdll@92

_REFROPdll

 

I think the _REFPROP@92 is the STDCALL, REFERENCE routine.

I would like to link to the _REFPROPdll routine.

I use this interface in my app:

subroutine REFPROPdll (hFld,hIn,hOut,iUnits,iMass,iFlag,a,b,z, &
Output,hUnits,iUCode,x,y,x3,q,ierr,herr)
!DIR$ ATTRIBUTES DLLIMPORT, DECORATE, ALIAS:'REFPROPdll' :: REFPROPdll
character, intent(in) :: hFld*10000, hIn*255, hOut*255
integer, intent(in) :: iUnits, iMass, iFlag
double precision, intent(in) :: a, b
double precision, intent(inout) :: z(20)
double precision, intent(out) :: Output(200)
character, intent(out) :: hUnits*255
integer, intent(out) :: iUCode
double precision, intent(out) :: x(20), y(20), x3(20), q
integer, intent(out) :: ierr
character, intent(out) :: herr*255
end subroutine

 

The global settings are

CVF (/iface:cvf) and Default

It generates access violations.

 

 

0 Kudos
Steve_Lionel
Honored Contributor III
1,964 Views

SYSTEMQQ also has a standard Fortran equivalent: EXECUTE_COMMAND_LINE.

0 Kudos
jimdempseyatthecove
Honored Contributor III
1,942 Views

A potential problem you can have is the provider is specifying the dimensions (ncmax, iPropMax) of the arrays whereas you are hardwiring your dimensions (20 and 200 respectively). As to if this is an issue or not, I cannot say. This should not exceed ncmax and iPropMax respectively.

 

>>

In the DLL two routines are defined

_REFPROPdll@92

_REFROPdll

<<

Did you mean _REFPROPdll?

 

Try:

subroutine REFPROPdll (hFld,hIn,hOut,iUnits,iMass,iFlag,a,b,z, &
Output,hUnits,iUCode,x,y,x3,q,ierr,herr) BIND(C,NAME='REFPROPdll')
!DIR$ ATTRIBUTES DLLIMPORT

If this complains, then add ", DECORATE" to the !DIR$ line.

 

Jim Dempsey

0 Kudos
mecej4
Honored Contributor III
1,937 Views

The REFPROP package contains subroutines whose arguments follow the convention that if the argument name begins with the letter 'h', that argument is of type CHARACTER. The libraries and DLLs provided with the package use a calling convention in which the lengths of those character variables are to be passed at the end, and the callees clean up the stack. I peeked into the 32-bit DLL, and I find that routines with the @NN decoration and  those without are identical. In fact, there is only one copy of code for each routine, with two entry names, one with @NN and another without.

There are two REFPROP packages available from NIST: a "MINI" version, which has a reduced set of substances and capabilities, and a purchased full version. The full version comes with the Fortran sources for the routines that compute the properties. The DLLs and LIBs mentioned by Wagner__Urs can be built from the sources. The Refprop package comes with a GUI app that calls the DLL and enables plotting the results, but the sources for the app are not provided.

Unless the user wishes to build Fortran DLLs that are to be called from Python, R, Excel, etc., I think that it is best to use the Fortran sources, ignore all DEC$ directives, libraries and DLLs, and build the user app as one would build any Fortran program.

0 Kudos
Wagner__Urs
Novice
1,916 Views

I think it is solved.

As mentioned I have the source of the REFPROP dll.

I build it new with the CVF (/iface:cvf) calling convention.

Then I can link this dll to my app without calling attributes.

There are no access violations.

Hitoshi
Novice
1,886 Views

Wagner_Urs

You already solved the problem by whole build process, but I think at your first step, there was a basic misunderstanding on the dll procedure here.
Please confirm followings.
Your program(s) calls REFPROPdll.dll, which is a wrapper function for precompiled REFPROP.dll.
REFPROPdll.dll calls REFPROP.dll.
REFPROP.dll calculates physicochemical properties.
But you showed "!DIR$ ATTRIBUTES DLLIMPORT,...." in your abbreviated REFPROPdll.dll code at 01-12-2022 06:21 AM !
REFPROPdll.dll should be DLLEXPORT status for your program.
Thus by removing DEC$ directives did solve the problem, I think.

0 Kudos
mecej4
Honored Contributor III
1,872 Views

@Hitoshi :

I think that Wagner_Urs  just wanted to get the program running.

The DLLs supplied by NIST are for calling from Excel, etc., and they do not exactly follow the calling and name decoration conventions of the most common Fortran compilers that are currently used on Windows.

It is possible to add DEC$ declarations or use C-Interoperability features and use the NIST-supplied DLLs, but the amount of expertise and work needed is not trivial. Wagner_Urs had the source code, and built a DLL or static library using a chosen compiler -- the same compiler that was used for the program that calls the routines in the RefProp library.

0 Kudos
Hitoshi
Novice
1,852 Views

mecej4;
Thank you for clarification on the matter.
The latest NIST source codes 10.0, which I have now, has following directory.
/FORTRAN---many source codes for FORTRAN *.FOR files, and subdirectory, DLLFILES
                  |
                 /DLLFILES--PAS_FTN.FOR

This PAS_FTN.FOR file contains subroutine REFPROPdll (hFld,hIn,hOut,iUnits,iMass,iFlag,a,b,z,
& Output,hUnits,iUCode,x,y,x3,q,ierr,herr).
In this topic, Wagner_Urs cited this 'REFPROPdll.FOR' as his code and DEC$ directive 'DLLIMPORT for subroutine itself' status.
This made me confused.

0 Kudos
Reply