将英特尔Visual Fortran程序链接到C++函数时遇到问题
我正试图将一个非常简单的C++函数链接到非常简单的英特尔Visual Fortran程序。将英特尔Visual Fortran程序链接到C++函数时遇到问题
Fortran程序看起来像这样在一个称为VFTestBed.f90)文件:
program VFTestBed
integer pInteger
pInteger = 11
call SimpleTest1(pInteger)
end program
的Fortran接口块看起来像这样(在称为interfaces.f90文件):
MODULE INTERFACES
interface
subroutine SimpleTest1(pInteger)
!DEC$ATTRIBUTES DECORATE, ALIAS: "SimpleTest1"
integer pInteger
end subroutine SimpleTest1
end interface
END MODULE
C++函数看起来像这样(在一个叫cppresponder.cpp的文件中):
#include <windows.h>
#include <sstream>
void SimpleTest1(int pInteger);
void SimpleTest1( int pInteger)
{
std::string pString = "";
std::string pTitle = "";
std::string pName = "SimpleTest1\0";
pString = "Integer was entered.";
pTitle = "In Routine: " + pName;
MessageBoxA(NULL, pString.c_str(), pTitle.c_str(), MB_OK | MB_ICONINFORMATION);
}
我研究过这个问题他们在Google上尝试了很多种不同的设置,声明,装饰等几十种排列和组合,但都无济于事。事实上,许多职位都很长并且相当复杂,而且往往似乎没有取得圆满结果。
在其他的事情,我曾尝试:
- 使得C++代码的.lib
- 使得使用各种形式的.DLL
- 的C++代码DEC $ ATTRIBUTES装饰,别名:!“ SimpleTest1"
- 使用BIND(C,...)使用使用装饰别名 平原别名
- 使用DUMPBIN使用前导的extern“C”
- 编译为C代码,看看在.DLL
- 符号210
- (禁用所有的C++构建体)
和很多其他的事情。我已经尝试了所有可能为其他海报工作的东西,绝对没有运气。
不管我做什么,我得到的功能_MAIN__
按照英特尔的地盘,我在CppResponder.DLL添加就像在源添加引用一个未解决的外部符号_SIMPLETEST1链接错误LNK2019消息文件。
如果有问题,我正在使用适用于Windows的Visual Studio Enterprise 2017和Intel Parallel Studio XE 2016 Update 4作曲家版,所有版本都在64位Windows 8.1机器上运行。
假设英特尔Fortran确实可以调用C++函数(我假设它可以),那么我必须缺少开关或设置某处。我已经使用Visual Studio提供的默认值设置了Fortran和C++项目。这两个项目都设置为Release | 86。
当然,这确实不能做那件难事。我已经花了大约12个小时,没有什么可以展示的。我在Fortran方面有数十年的经验,但对C++来说相当新颖。
有没有人以前做过这件事,并会愿意走过我如何做到这一点?
由于提前,
鲍勃·凯泽
cppresponder.cpp
#include <iostream>
extern "C" void simpletest_(int* i){
std::cout << "cpp " << *i << '\n';
}
VFTestBed.cpp
program VFTestBed
integer pInteger
pInteger = 11
call simpletest(pInteger)
end program
编译:
g++ -c cppresponder.cpp; gfortran -c VFTestBed.f90; gfortran -o test.o cppresponder.o VFTestBed.o -l stdc++
高管:
./test.o
输出
>cpp 11
可能还需要这些编译器开关
g++ -c -Wpadded -Wpacked -malign-double -mpreferred-stack-boundary=8 cppresponder.cpp; gfortran -c -malign-double VFTestBed.f90
谢谢,我希望使用英特尔Fortran和Visual Studio来完成此任务。如果英特尔路线空白,我会研究这一点。 –
啊!我没有VS在那里尝试。但是,由于使用gcc工具链可以正常工作,所以翻译起来可能不太难。我不知道有关微软的东西。无论如何,如果它有任何帮助,那么好,如果不是,那么我们可以称之为研究实验:) – systemcpro
我要感谢上述反应。我尝试了他们的建议,但没有得到任何地方。
但经过更多的悲伤,我找到了一些工作。
的Fortran:
program VFTestBed
use INTERFACES
integer pInteger
pInteger = 11
call SimpleTest1(pInteger)
end program
MODULE INTERFACES
interface
subroutine SimpleTest1(pInteger)
!DEC$ ATTRIBUTES ALIAS:'[email protected]@[email protected]' :: SimpleTest1
integer pInteger
end subroutine SimpleTest1
end interface
END MODULE
和在C++侧:
#define WIN32_DEFAULT_LIBS
#include <windows.h>
#include <iostream>
#include <sstream>
__declspec(dllexport) void SimpleTest1(int* pInteger);
void SimpleTest1(int* pInteger)
{
std::string pString = "";
std::string pTitle = "";
std::string pName = "SimpleTest1\0";
pString = "Integer entered = " + std::to_string(*pInteger);
pTitle = "In Routine: " + pName;
MessageBoxA(NULL, pString.c_str(), pTitle.c_str(), MB_OK | MB_ICONINFORMATION);
}
的显着变化:
- 加入__declspec(DLLEXPORT)
- 改变INT为int *
- 加入的#define WIN32_DEFAULT_LIBS
- 从.DLL改变为用于DUMPBIN找出C++名称修饰
- 在主程序的.lib
- 中添加的接口添加使用接口
- :DEC $ ATTRIBUTES ALIAS: '?SimpleTest1 @@ YGXPAH @ Z' :: SimpleTest1
所以,这一切得到的代码不超过30行编译,链接和运行!啧!
15+小时的生活我永远不会回来。
无论如何,它已经解决了,我希望我挽救了一些未来的读者,使我从所经历的悲痛中解脱出来。我希望某个地方的人认为这很有用。
无法解决您的问题,但我可能会为您添加一块拼图。你将不得不声明C++函数为extern“C”,因为fortran永远不会理解C++名称的改变(按照https://people.sc.fsu.edu/~jburkardt/f_src/f90_calls_c++/f90_calls_c++.html) – systemcpro
谢谢,我试过了,就像你在网站上看到的那样,但是这似乎并没有成功。我必须在某个地方失去某些东西。 –