LNK2001 and LNK2019 unresolved external symbols -- Link errors in a Visual C++ / Intel Visual Fortran Solution

LNK2001 and LNK2019 unresolved external symbols -- Link errors in a Visual C++ / Intel Visual Fortran Solution

My MS Visual Studio 2010 Professional Solution Explorer is comprised of three projects in the solution. The main project is a Visual C++ main Console Application that includes a single .c source main module and one supporting .h header file (call the project 'cmain'). The other two projects are respectively: a) a Visual C++ Class Library (call it 'clib') composed of many .c source and .h header files; and b) an Intel Visual Fortran Library (call it 'flib') composed of many .f source and .inc include files. The C routines call the Fortran routines, and some of the Fortran routines call the C routines.

All of the Fortran and C successfully compile. The flib project successfully builds a '.lib'. And the path to the flib .lib is included as an "Additional Dependencies" in the Linker 'Input' properties page of both the cmain and clib projects.

The Project Build Order for the Solution is as follows: flib, clib, cmain (where cmain depends on clib and clib depends on flib).

I'm encountering LNK2001 and LNK2019 unresolved external symbols related to Pointers to the Fortran entry and commons (include files) in the cmain and clib projects.

An example of one of the LNK2019 errors in the Error List is:
.......Description.........................................................................................................................File.............Project
### error LNK2019: unresolved external symbol ctr_entry_ referenced in function main.......ctr.obj........ctr_cmain

Within source file ctr.c is:
extern void ctr_entry_(callingargs);

There then also exists a Fortran source routine 'ctr_entry.f' that begins with 'SUBROUTINE ctr_entry (callingargs)' that is the target of the 'extern void ctr_entry_' statement of the ctr.c file noted above.

An example of one of the LNK2001 errors in the error list is:
.......Description.......................................................................................................File................................Project
### error LNK2001: unresolved external symbol run_option_common_ ctr........CleanRoutines.obj........ctr_clib

A snippet from the C routine flagged with this LNK2001 error is:

void

clean_run_option_()

{

cleanRunOption(&run_option_common_);

}

The &pointer to 'run_option_common_' above is targeting a 'run_option_common.inc' which is one of the includes in the flib project.

In either the LNK2001 or LNK2019 cases, I believe the external symbols to the Fortran should get resolved by the inclusion of the path to the flib .lib file that I've specifically included in the Linker 'Input' 'Additional Dependencies' property page of both the cmain and clib projects.

But obviously something is not set right to resolve the external symbols to the Fortran from the C by the Linker.

I'm happy to provide additional information including specifics of other MSVS 2010 Professional project settings in the Solution.

Appreciate any questions, comments, guidance toward resolution of these LNK errors.

7 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

Are you aware that Intel Fortran on Windows creates global names that are the routine (or COMMON) name upcased? From what you have shown so far, it seems your code assumes UNIX/Linux conventions with lowercase names and a trailing underscore, neither of which are the convention on Windows

There are various ways to resolve this.

1. Add BIND(C,NAME="lower-case-name_") after the argument list of each Fortran procedure that gets called from C. Depending on what the arguments are, this may or may not provoke other errors. Note the trailing underscore in the NAME= string.
2. In each routine, add:

!DEC$ ATTRIBUTES DECORATE,ALIAS:"lower-case-name_" :: routine-name

3. Change the C code to reference upper-case names without the trailing underscore.

Retired 12/31/2016

Steve,

Thank you. Very useful insights you've provided. I will follow your resolution suggestions and let you know. . . .

Steve,

I too have had problems linking a fortran dll to my C++ project. I have read many of your posts, and tried to do everything they said, but to no avail.

I originally compiled the fortran dl and libraries on compact visual fortran and for use with visual basic 6 for which everything worked flawlessly.The problem is that when I try to link it to a C project (tried to link this with both my latest VS2010, and old VStudio 6.0) I keep getting the same error:

test.obj : error LNK2001: unresolved external symbol __imp__grand, or

test.obj : error LNK2001: unresolved external symbol _grand

if I don't use __declspec( dllimport ). When I run dumpbin /exports I get:

E:\Joel_fujitsu\c++\gausfitdll\Debug>dumpbin -exports gausfit.lib

Microsoft COFF Binary File Dumper Version 6.00.8447

Copyright (C) Microsoft Corp 1992-1998. All rights reserved.

Dump of file gausfit.lib

File Type: LIBRARY

Exports

ordinal name

Linefit

Minuit

g2

gausfit1

grand

sinfit

Summary

C6 .debug$S

14 .idata$2

14 .idata$3

4 .idata$4

4 .idata$5

C .idata$6

I paste one example of a function from the fortran dll and the main program from the c++ routine:
What it seems like is that the prepending underscore is screwing things up, what I don't understand is why this works flawlessly with visual basic? There is of course an alias directive in VB which I believe doesn't mangle the names so perhaps that is why, but any possible solution would be of great help. I was considering prepending the alias in the fortran file with an "_". I've also tried all forms of __STDCALL and extern "C++", _cdecl, etc.

Looking forward to you help!

!*********************************

! generate a gaussian random number

!**********************************

real function grand

! Expose subroutine gausfit to users of this DLL

!DEC$ ATTRIBUTES DLLEXPORT::grand

!DEC$ ATTRIBUTES ALIAS : "grand" :: grand !This sets its name

real x

integer i

i = 1

call rnorml(x,i)

grand = x

end function

#include "stdafx.h"

extern "C" __declspec( dllimport ) float grand();

int main(int argc, char* argv[])

{

float f;

f = grand();

return 0;

}

Change:

!DEC$ ATTRIBUTES ALIAS : "grand" :: grand

to:

!DEC$ ATTRIBUTES DECORATE, ALIAS : "grand" :: grand

The C++ compiler is adding a leading underscore, which is the standard name "decoration" on 32-bit Windows, but your use of ALIAS told Fortran not to add the underscore. Inserting DECORATE tells Fortran to do whatever the appropriate decoration is for the platform.

Retired 12/31/2016

Thank you, it seemed like something like this glad to have an expert like you out there, you just saved me another day of work. I copied the original example from the examples , but must have missed that keyword option.

Thanks!

Joel

Glad to hear it. For completeness, you could also ditch the ATTRIBUTES ALIAS line entirely and use this instead:

function grand () BIND(C)
use, intrinsic :: ISO_C_BINDING
real(C_FLOAT) :: grand

You still need the DLLEXPORT directive, though. I'd encourage you to use the standard Fortran C interoperability features where possible.

Retired 12/31/2016

Leave a Comment

Please sign in to add a comment. Not a member? Join today