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

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

Wagner__Urs
Novice
901 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
Black Belt
823 Views

Try:

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

Jim Dempsey

Steve_Lionel
Black Belt Retired Employee
817 Views

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

call GET_ENVIRONMENT_VARIABLE('envname',stringvar)
Wagner__Urs
Novice
792 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?

 

Mark_Lewy
New Contributor III
786 Views

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

Wagner__Urs
Novice
782 Views

Yes there is only an access violation exception window.

Mark_Lewy
New Contributor III
776 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?

andrew_4619
Honored Contributor II
767 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.

jimdempseyatthecove
Black Belt
749 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

Wagner__Urs
Novice
712 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

Mark_Lewy
New Contributor III
708 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-...

 

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

mecej4
Black Belt
695 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.

Wagner__Urs
Novice
692 Views

Thank You for Your explanation., it helps.

Yes I know I jump from one idea to another.

 

Wagner__Urs
Novice
678 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.

 

 

Steve_Lionel
Black Belt Retired Employee
669 Views

SYSTEMQQ also has a standard Fortran equivalent: EXECUTE_COMMAND_LINE.

jimdempseyatthecove
Black Belt
647 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

mecej4
Black Belt
642 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.

Wagner__Urs
Novice
621 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
591 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.

mecej4
Black Belt
577 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.

Hitoshi
Novice
557 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.

Reply