C++ 混合编程:从C++;

C++ 混合编程:从C++;,c++,c,dll,fortran,C++,C,Dll,Fortran,我试图用命令行编译一个混合程序 编译工具是英特尔visual fortran 2013和VS 2013 我搜索了一下,发现使用dll比lib更容易 所以我试着把我的fortran源代码编译成一个dll文件 myFortran源代码: ! forsubs.f90 ! ! FUNCTIONS/SUBROUTINES exported from FORSUBS.dll: ! FORSUBS - subroutine ! INTEGER*4 FUNCTION Fact (n) !

我试图用命令行编译一个混合程序

编译工具是英特尔visual fortran 2013和VS 2013

我搜索了一下,发现使用
dll
lib
更容易

所以我试着把我的fortran源代码编译成一个dll文件

my
Fortran
源代码:

!  forsubs.f90 
!
!  FUNCTIONS/SUBROUTINES exported from FORSUBS.dll:
! FORSUBS      - subroutine 
!
INTEGER*4 FUNCTION Fact (n)
   !DEC$ ATTRIBUTES DLLEXPORT::Fact
      INTEGER*4 n [VALUE]
      INTEGER*4 i, amt
      amt = 1
      DO i = 1, n
        amt = amt * i
      END DO
      Fact = amt
   write(*,*)"Mixed calls succeed!"
END
SUBROUTINE Pythagoras (a, b, c)
   !DEC$ ATTRIBUTES DLLEXPORT::Pythagoras
      REAL*4 a [VALUE]
      REAL*4 b [VALUE]
      REAL*4 c [REFERENCE]
      c = SQRT (a * a + b * b)
END
my
C++
源代码:C_main.cpp

/*     File CMAIN.C   */

#include <stdio.h>

extern int __stdcall fact(int* n);
extern void __stdcall pythagoras(float* a, float* b, float *c);

int main()
{
    float c;
    printf("Factorial of 7 is: %d\n", FACT(7));
    PYTHAGORAS (30, 40, &c);
    printf("Hypotenuse if sides 30, 40 is: %f\n", c);
}
此外,我还尝试以另一种方式加载dll,方法是使用:

 HINSTANCE hLibrary=LoadLibrary("forsubs.dll"); 
 if(hLibrary==NULL)
 {
  cout<<"can't find the dll file"<<endl;
  return -1;
 }
另外,我在谷歌上搜索过,有人说
\uu stdcall
不是必需的,我删除了,但仍然得到了错误:

error LNK2019: unresolved external symbol _FACT referenced in function _main
error LNK2019: unresolved external symbol _PYTHAGORAS referenced in function _main
我想这可能是同样的问题。但我自己解决不了

附言: 我的
dll
lib
的信息:

D:\c_f\c_f_dll>dumpbin /exports forsubs.lib
Microsoft (R) COFF/PE Dumper Version 12.00.30501.0
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file forsubs.lib

File Type: LIBRARY

     Exports

       ordinal    name

                  FACT
                  PYTHAGORAS

  Summary

          C3 .debug$S
          14 .idata$2
          14 .idata$3
           8 .idata$4
           8 .idata$5
           C .idata$6

D:\c_f\c_f_dll>dumpbin /exports forsubs.dll
Microsoft (R) COFF/PE Dumper Version 12.00.30501.0
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file forsubs.dll

File Type: DLL

  Section contains the following exports for forsubs.dll

    00000000 characteristics
    5477F1C5 time date stamp Fri Nov 28 11:53:41 2014
        0.00 version
           1 ordinal base
           2 number of functions
           2 number of names

    ordinal hint RVA      name

          1    0 00001000 FACT
          2    1 000010B0 PYTHAGORAS

  Summary

        1000 .data
        1000 .pdata
        1000 .rdata
        1000 .reloc
        1000 .text
编辑2
它仍然不起作用。

C/C++区分大小写,因此如果调用
FACT
,那么它必须声明为
FACT
,而不是
FACT
。或者反过来说

您需要声明您的函数(在C++代码中)为<代码>外部“C”<代码>,以禁用否则将被假定为C++特定的名称修改。

\uu stdcall
确实是Fortran函数的正确调用约定(默认情况下)

Fortran不区分大小写(默认情况下,它可以通过编译器选项进行更改,这很愚蠢)。我相信“英特尔Fortran编译器”会为Fortran函数(例如,名为“事实”的函数将导出为“事实”)生成所有大写符号(用于链接目的)。因此,您需要在C++声明中匹配该情况。我不确定Fortran符号的使用方式(全大写或全小写),因此,如果其中一个不起作用,请尝试另一个

编辑2:

对于原型,我相信这些是C++中正确的形式(我不确定,因为我在FORTRAN中很生疏):< /P> <代码>包含//在C中,或在C++中(但必须使用STD::It3xt) 外部“C”declspec(dllimport)int32\u t\u stdcall事实(int32\t n); 外部“C”uu declspec(dllimport)void uu stdcall毕达哥拉斯(浮点数a、浮点数b、浮点数*C);
请注意,对于4字节整数,您需要使用
int32\t
,对于Fortran中的
[VALUE]
类型,它也应该在C/C++中按值传递。。。至少,这是我对它的理解(但正如我所说,我不是Fortran专家)。

我不知道你的情况,但Fortran dll文件只有函数,但没有任何dllmain开关语句或createthread函数。记住为loadlibrary提供正确的目录/路径。@Amadan,您好,我在代码中添加了
“C”
,但得到了同样的错误。我认为stdcall的必要性取决于“混合编程:从C调用FORTRAN”这个问题。你知道我问题的第二条路吗?是的,我错了,我道歉。阅读可能是件好事,我不应该猜测我显然不太了解的事情。@Bot我将
dll
放在与
exe
相同的目录中,但仍然找不到
dll
。我建议使用Fortran的ISO_C_绑定,而不是扩展或以前的技术。Stackoverflow在此主题上有一个标记:您好,我编辑了我的代码,但出现了另一个错误,我已更新了我的问题。@对不起。。。我已经有一段时间没有使用DLL、MSVC导入库或Windows了。。所以我对这些东西有点生疏了,没有任何东西可以测试。我认为,如果要链接导入库(即.lib文件),则需要在
extern“C”
和返回类型之间的函数声明中添加
\u declspec(dllimport)
。stdcall不是OP使用的Fortran编译器的默认调用约定。
error LNK2019: unresolved external symbol _FACT referenced in function _main
error LNK2019: unresolved external symbol _PYTHAGORAS referenced in function _main
D:\c_f\c_f_dll>dumpbin /exports forsubs.lib
Microsoft (R) COFF/PE Dumper Version 12.00.30501.0
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file forsubs.lib

File Type: LIBRARY

     Exports

       ordinal    name

                  FACT
                  PYTHAGORAS

  Summary

          C3 .debug$S
          14 .idata$2
          14 .idata$3
           8 .idata$4
           8 .idata$5
           C .idata$6

D:\c_f\c_f_dll>dumpbin /exports forsubs.dll
Microsoft (R) COFF/PE Dumper Version 12.00.30501.0
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file forsubs.dll

File Type: DLL

  Section contains the following exports for forsubs.dll

    00000000 characteristics
    5477F1C5 time date stamp Fri Nov 28 11:53:41 2014
        0.00 version
           1 ordinal base
           2 number of functions
           2 number of names

    ordinal hint RVA      name

          1    0 00001000 FACT
          2    1 000010B0 PYTHAGORAS

  Summary

        1000 .data
        1000 .pdata
        1000 .rdata
        1000 .reloc
        1000 .text
Also, I have tried to add a header:
#ifdef FORSUBS_EXPORTS
#define FORSUBS_API __declspec(dllexport) 
#else
#define FORSUBS_API __declspec(dllimport) 
#endif
#include <stdint.h>  // in C, or <cstdint> in C++ (but must use std::int32_t)

extern "C" __declspec(dllimport) int32_t __stdcall FACT(int32_t n);
extern "C" __declspec(dllimport) void __stdcall PYTHAGORAS(float a, float b, float *c);