首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用.lib和Fortran /调用c++ /未解析外部符号调用c++代码创建c++文件

使用.lib和Fortran /调用c++ /未解析外部符号调用c++代码创建c++文件
EN

Stack Overflow用户
提问于 2013-01-29 18:59:17
回答 1查看 2.8K关注 0票数 0

我试图创建一个.lib库文件,其中包含调用c++函数的Fortran函数,但我得到了令人生畏的"error LNK2019:未决外部符号.“。这些代码最终将与一堆其他库一起编译为DLL,并在一个单独的程序(PSSE)中使用。当PSSE计划使用我的库创建DLL时,我会得到编译错误。下面是我试图使用的代码,后面是编译代码。代码应该将两个数字相加并输出答案。

fort_code.f

代码语言:javascript
复制
  SUBROUTINE TESTCPP ( II, JJ, KK, LL )
  INCLUDE 'COMON4.INS'

  integer*4, external :: CPPFUNCTION

  INTEGER a, b, c, test

  IF (.NOT. IFLAG) RETURN

  a = ICON(II)
  b = ICON(II + 1)
  test = CPPFUNCTION( a , b, c )
  WRITE ( ITERM, * ) 'C = ', c
  RETURN
  END

cpp_code.cpp

代码语言:javascript
复制
extern "C" {
      void _CPPFUNCTION(int a, int b, int *c);
}

void _CPPFUNCTION(int a, int b, int *c) {
      *c = a + b;
    }

compile.bat

代码语言:javascript
复制
cl /nologo /MD /c /W3 /O2 /FD /EHsc /errorReport:prompt /D"MSWINDOWS" /D"WIN32" ^
   /D"_WINDOWS" /D"NDEBUG" "cpp_code.cpp"

IFORT /nologo /Od /Oy- /assume:buffered_io /traceback /libs:dll /threads /c /Qip ^
      /extend_source:132 /noaltparam /fpscomp:logicals /warn:nodeclarations ^
      /warn:unused /warn:truncated_source /Qauto /Op /iface:cvf /define:DLLI ^
      /include:"C:\Program Files (x86)\PTI\PSSE32\PSSLIB" ^
      /object:"fort_code.OBJ" ^
      "fort_code.f" 

lib /out:fort_cpp.lib fort_code.obj cpp_code.obj

当PSSE程序试图创建DLL时,我得到的输出如下:

代码语言:javascript
复制
 ifort /nologo /assume:buffered_io /traceback /libs:dll /threads /c /Qip /extend_source:132 /noaltparam /fpscomp:logicals /Qprec /warn:declarations /warn:unused /warn:truncated_source /Qauto /fp:source /iface:cvf /define:DLLI /include:"C:\Program Files (x86)\PTI\PSSE32\PSSLIB" /object:"C:\temp\INIT_620289\11hw2ap_conec.obj" /module:"C:\temp\INIT_620289" "11hw2ap_conec.f"


 ifort /nologo /assume:buffered_io /traceback /libs:dll /threads /c /Qip /extend_source:132 /noaltparam /fpscomp:logicals /Qprec /warn:declarations /warn:unused /warn:truncated_source /Qauto /fp:source /iface:cvf /define:DLLI /include:"C:\Program Files (x86)\PTI\PSSE32\PSSLIB" /object:"C:\temp\INIT_620289\11hw2ap_conet.obj" /module:"C:\temp\INIT_620289" "11hw2ap_conet.f"


 link /INCREMENTAL:NO /NOLOGO /DLL /SUBSYSTEM:WINDOWS /MACHINE:X86 /ERRORREPORT:PROMPT @"C:\temp\INIT_620289\linkfilestod9p1.txt" /OUT:"C:\temp\INIT_620289\11hw2ap_dsusr.dll" /map:"C:\temp\INIT_620289\11hw2ap_dsusr.map"

 fort_cpp.lib(fort_code.obj) : error LNK2019: unresolved external symbol _CPPFUNCTION@12 referenced in function _TESTCPP
 C:\temp\INIT_620289\11hw2ap_dsusr.dll : fatal error LNK1120: 1 unresolved externals

 ERROR during link(1)... Aborted

conec/conet只是对外部库函数的Fortran调用:

代码语言:javascript
复制
      SUBROUTINE CONEC
C
      INCLUDE 'COMON4.INS'
C
      CALL TESTCPP         ( 55791,     0,     0,     0)
C
      RETURN
      END
      SUBROUTINE CONET
C
      INCLUDE 'COMON4.INS'
C
      IF (.NOT. IFLAG) GO TO 9000
C
C  NETWORK MONITORING MODELS
C
C
 9000 CONTINUE
C
      RETURN
      END

我看到了从Fortran调用c++函数的几个不同的例子,但它们看起来都略有不同。我注意到的一件事是_在c++函数名称之前或之后的不同用法。我如何知道使用哪个:_CPPFUNCTIONCPPFUNCTIONCPPFUNCTION_。我是否需要在c++中使用__declspec( dllexport )导出函数?我需要在Fortran代码中创建一个ALIAS:'_CPPFUNCTION'吗?

我使用以下编译器: ifort: IVFIA-32 v12.1.0.233 cl: v16.00.30319.01 x86

我是否缺少一些东西来正确地将c++代码链接到Fortran函数?

EN

回答 1

Stack Overflow用户

发布于 2013-01-29 21:32:00

问题是有很多选择。没有,一个或两个下划线之前和之后,字符串长度后的变量或在列表的末尾,调用的值或调用通过引用。大写的、小写的或原始的命名。就这些选项而言,正确的概率已经低于1/ 100 (1/3*1/3*1/2*1/2*1/3)。

您可以通过使用.lib实用工具内省.lib文件并手动检查intel fortran默认设置和项目文件中的设置来稍微减少它。

正如一些人所建议的,最优雅的方法是使用bind(C)绑定模块的组合。bind(C)语句避免了必须知道名称mangling。iso_c_bindings提供了C字串integer(c_int),而不是integer*4,以确保您的类型与C兼容。您必须知道,默认情况下,fortran调用是引用的,并且可以使用, value进行值调用。这应该会把你的成功率提高到1。

下面是如何调用在下面的add1中定义的c++函数的一个简单示例:

test.f90

代码语言:javascript
复制
  program example

    use iso_c_binding
    implicit none

    interface
       integer(c_int) function add1(x) bind(C,name="add1")
         !DEC$ ATTRIBUTES DLLEXPORT :: add1
         use iso_c_binding
         integer(c_int), value :: x
       end function add1
    end interface

    call callingadd1()
  contains
    subroutine callingadd1()
      write(*,*) '1+1=', add1(1)
    end subroutine callingadd1
  end program example

add1.cpp

代码语言:javascript
复制
extern "C" {
  int add1(int x);
}

int add1(int x) {
  return(x+1);
}

只使用子例程编辑示例。以便包含在共享对象/dll/dylib中。

subroutineonly.f90

代码语言:javascript
复制
subroutine callingadd1() bind(C, name="callingadd1")
  !DEC$ ATTRIBUTES DLLEXPORT :: callingadd1
  use iso_c_binding
  implicit none
  interface
     integer(c_int) function add1(x) bind(C,name="add1")
       !DEC$ ATTRIBUTES DLLEXPORT :: add1
       use iso_c_binding
       integer(c_int), value :: x
     end function add1
  end interface
  write(*,*) '1+1=', add1(1)
end subroutine callingadd1
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14590235

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档