- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
Appreciate any questions, comments, guidance toward resolution of these LNK errors.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you. Very useful insights you've provided. I will follow your resolution suggestions and let you know. . . .
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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;
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
!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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks!
Joel
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page