Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Beginner
198 Views

How to link a C++ static library to Fortran main program in Microsoft Visual studio

Hi,

I am using Fortran to call a static library in C++

The C++ static library is 

# include <stdlib.h>
# include <stdio.h>
//#include <iostream>

//using namespace std;

#ifdef __cplusplus
extern "C" 
{
#endif
void print_C ( char *text )
{
  //string file;
  printf ( "%s\n", text );
  //file = " Hello, world. ";
  //cout<<"Hello, world.";

  return;
}
#ifdef __cplusplus
}
#endif

and the Fortran main code is

program main

  use iso_c_binding, only : C_CHAR, C_NULL_CHAR
  implicit none

  interface
    subroutine print_c ( string ) bind ( C, name = "print_C" )
      use iso_c_binding, only : C_CHAR
      character ( kind = C_CHAR ) :: string ( * )
    end subroutine print_c
  end interface

  call print_C ( C_CHAR_"Hello World!" // C_NULL_CHAR )
end

This give a right result.

But if I use a C++ head for std::iostream, the linking procedure would have some error

# include <stdlib.h>
# include <stdio.h>
#include <iostream>

//using namespace std;

#ifdef __cplusplus
extern "C" 
{
#endif
void print_C ( char *text )
{
  //string file;
  printf ( "%s\n", text );
  //file = " Hello, world. ";
  std::cout<<"Hello, world.";

  return;
}
#ifdef __cplusplus
}
#endif

Some typical error would be:

Error    8     error LNK2019: unresolved external symbol "void __cdecl std::_Xout_of_range(char const *)" (?_Xout_of_range@std@@YAXPBD@Z) referenced in function "public: void __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::_Xran(void)const " (?_Xran@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEXXZ)    test_for_c++_lib.lib(for_c++.obj)    
 

If I include the head file <iostream> in the scope of extern "C" the building of static library will have some error

# include <stdlib.h>
# include <stdio.h>

//using namespace std;

#ifdef __cplusplus
extern "C" 
{
#endif

#include <iostream>
void print_C ( char *text )
{
  //string file;
  printf ( "%s\n", text );
  //file = " Hello, world. ";
  std::cout<<"Hello, world.";

  return;
}
#ifdef __cplusplus
}
#endif

Error    1    error C2894: templates cannot be declared to have 'C' linkage    c:\program files (x86)\microsoft visual studio 11.0\vc\include\xtr1common    15    1    test_for_c++_lib
 

 

What should I do to make the fortran linker correctly linking the C++ static library?

0 Kudos
6 Replies
Highlighted
Valued Contributor III
198 Views

You don't show any details regarding your toolsets nor anything with compiler/linker options or steps you tried.

Noting __cplusplus is a predefined macro in Microsoft C++ compiler (https://docs.microsoft.com/en-us/cpp/preprocessor/predefined-macros?view=vs-2017), see the following.  You can compare and contrast your situation with that below and try to figure out why you get the errors.

C:\Temp>type print_C.cpp
# include <stdlib.h>
# include <stdio.h>
#include <iostream>

//using namespace std;

#ifdef __cplusplus
extern "C"
{
#endif
void print_C ( char *text )
{
  //string file;
  printf ( "%s\n", text );
  //file = " Hello, world. ";
  std::cout<<"Hello, world.";

  return;
}
#ifdef __cplusplus
}
#endif

C:\Temp>cl /c print_C.cpp
Microsoft (R) C/C++ Optimizing Compiler Version 19.16.27027.1 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.

print_C.cpp
C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Tools\MSVC\14.16.27023\include\xlocale(319):
warning C4530: C++ exception handler used, but unwind semantics are not enabled. Specify /EHsc

C:\Temp>type main.f90
program main

  use iso_c_binding, only : C_CHAR, C_NULL_CHAR
  implicit none

  interface
    subroutine print_c ( string ) bind ( C, name = "print_C" )
      use iso_c_binding, only : C_CHAR
      character ( kind = C_CHAR ) :: string ( * )
    end subroutine print_c
  end interface

  call print_C ( C_CHAR_"Hello World!" // C_NULL_CHAR )
end


C:\Temp>ifort /c /standard-semantics main.f90
Intel(R) Visual Fortran Intel(R) 64 Compiler for applications running on Intel(R) 64,
Version 19.0.3.203 Build 20190206
Copyright (C) 1985-2019 Intel Corporation.  All rights reserved.


C:\Temp>link print_C.obj main.obj /subsystem:console -out:main.exe
Microsoft (R) Incremental Linker Version 14.16.27027.1
Copyright (C) Microsoft Corporation.  All rights reserved.


C:\Temp>main.exe
Hello World!
Hello, world.
C:\Temp>

 

0 Kudos
Highlighted
Beginner
198 Views

Thank you very much for your reply.

I have tried your procedure on my computer, the compiling procedure worked alright, but the linking procedure had some problems.

Compiling C++ obj file:

P:\Guo_Li\codes\test\test_cmd_for_c++>cl /c print_c.cpp
Microsoft (R) C/C++ Optimizing Compiler Version 17.00.60610.1 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.

print_c.cpp
C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\INCLUDE\xlocale(336) : wa
rning C4530: C++ exception handler used, but unwind semantics are not enabled. S
pecify /EHsc

P:\Guo_Li\codes\test\test_cmd_for_c++>

The compiling of Fortran had a warning but still gave a obj file

P:\Guo_Li\codes\test\test_cmd_for_c++>ifort /c /standard-semantics main.f90
Intel(R) Visual Fortran Intel(R) 64 Compiler Professional for applications runni
ng on Intel(R) 64, Version 11.1    Build 20091012 Package ID: w_cprof_p_11.1.051

Copyright (C) 1985-2009 Intel Corporation.  All rights reserved.
ifort: command line warning #10006: ignoring unknown option '/standard-semantics'

The error from link is

P:\Guo_Li\codes\test\test_cmd_for_c++>link print_c.obj main.obj /subsystem:conso
le -out:main.exe
Microsoft (R) Incremental Linker Version 9.00.21022.08
Copyright (C) Microsoft Corporation.  All rights reserved.

print_c.obj : warning LNK4229: invalid directive '/FAILIFMISMATCH:_MSC_VER=1700'
 encountered; ignored
print_c.obj : warning LNK4229: invalid directive '/FAILIFMISMATCH:_ITERATOR_DEBU
G_LEVEL=0' encountered; ignored
print_c.obj : warning LNK4229: invalid directive '/FAILIFMISMATCH:RuntimeLibrary
=MT_StaticRelease' encountered; ignored
print_c.obj : error LNK2019: unresolved external symbol "void __cdecl std::_Xbad
_alloc(void)" (?_Xbad_alloc@std@@YAXXZ) referenced in function "char * __cdecl s
td::_Allocate<char>(unsigned __int64,char *)" (??$_Allocate@D@std@@YAPEAD_KPEAD@
Z)
print_c.obj : error LNK2019: unresolved external symbol "void __cdecl std::_Xlen
gth_error(char const *)" (?_Xlength_error@std@@YAXPEBD@Z) referenced in function
 "public: void __cdecl std::basic_string<char,struct std::char_traits<char>,clas
s std::allocator<char> >::_Xlen(void)const " (?_Xlen@?$basic_string@DU?$char_tra
its@D@std@@V?$allocator@D@2@@std@@QEBAXXZ)
print_c.obj : error LNK2019: unresolved external symbol "void __cdecl std::_Xout
_of_range(char const *)" (?_Xout_of_range@std@@YAXPEBD@Z) referenced in function
 "public: void __cdecl std::basic_string<char,struct std::char_traits<char>,clas
s std::allocator<char> >::_Xran(void)const " (?_Xran@?$basic_string@DU?$char_tra
its@D@std@@V?$allocator@D@2@@std@@QEBAXXZ)
print_c.obj : error LNK2019: unresolved external symbol "char const * __cdecl st
d::_Syserror_map(int)" (?_Syserror_map@std@@YAPEBDH@Z) referenced in function "p
ublic: virtual class std::error_condition __cdecl std::_System_error_category::d
efault_error_condition(int)const " (?default_error_condition@_System_error_categ
ory@std@@UEBA?AVerror_condition@2@H@Z)
print_c.obj : error LNK2019: unresolved external symbol "char const * __cdecl st
d::_Winerror_map(int)" (?_Winerror_map@std@@YAPEBDH@Z) referenced in function "p
ublic: virtual class std::basic_string<char,struct std::char_traits<char>,class
std::allocator<char> > __cdecl std::_System_error_category::message(int)const "
(?message@_System_error_category@std@@UEBA?AV?$basic_string@DU?$char_traits@D@st
d@@V?$allocator@D@2@@2@H@Z)
main.exe : fatal error LNK1120: 5 unresolved externals

P:\Guo_Li\codes\test\test_cmd_for_c++>

My fortran compiler version is 11.1

Intel(R) Visual Fortran Intel(R) 64 Compiler Professional for applications runni
ng on Intel(R) 64, Version 11.1    Build 20091012 Package ID:

and both C++ and fortran are build for x64.

Does the fortran property "/standard-semantics" matters?

0 Kudos
Highlighted
Black Belt
198 Views

ifort 11.1 would not be compatible with any currently supported version of Visual Studio.  It may be difficult for us to comment usefully even if you have an old version which matches.

-standard-semantics would not have a bearing on this.

0 Kudos
Highlighted
Beginner
198 Views

Thank you very much for your reply. 

It seems that I'd better change a fortran compiler to be compatible.

0 Kudos
Highlighted
Valued Contributor III
198 Views

Port, Phillip wrote:

Thank you very much for your reply. 

It seems that I'd better change a fortran compiler to be compatible.

Yes, if possible please upgrade your compiler and consider even the latest version 19.0 (and up to Update 3 with this version) where you will then have the option of utilizing features from enhanced interoperability with C from Fortran 2018 standard, should that be of value to you.  You will also then benefit from many a bug resolution in all manner of modern Fortran features but also with C interoperability and procedure arguments with VALUE attribute, etc.

Re: standard-semantics, refer to online Intel Fortran documentation, particularly the second link below on Data Types which states, "If you are going to use LOGICAL types to interoperate with C, specify the option fpscomp[:]logicals to change the interpretation to be C-like. This is included when using the option standard-semantics, which is recommended for using Fortran 2003 (or later) features":  So I tend to employ /standard-semantics reflexively with modern Fortran code.

https://software.intel.com/en-us/fortran-compiler-developer-guide-and-reference-standard-semantics

https://software.intel.com/en-us/fortran-compiler-developer-guide-and-reference-data-types

 

0 Kudos
Highlighted
Beginner
198 Views

Thank you very much for your comments.

0 Kudos