经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 数据库/运维 » Windows » 查看文章
Windows下C++/Fortran调用.exe可执行文件
来源:cnblogs  作者:0xzhang  时间:2021/4/12 9:46:05  对本文有异议

软件环境

  1. # 操作系统 = Windows10
  2. # 编译链工具 =
  3. # gcc, g++, GNU Fortran (MinGW.org GCC Build-2) 9.2.0
  4. # GNU Make 3.82.90 Built for i686-pc-mingw32
  5. # GNU ld (GNU Binutils) 2.32
  6. # CMake version 3.18.1

本机安装了MinGW编译工具,并将<安装路径>\MinGW\bin添加到环境变量中。

Windows下CMake编译配置

设置项目的generator

在本机使用CMake过程中发现,默认使用NMake Makefiles作为generator,因为没有安装因此配置失败。

希望设置generator为已安装的MinGW Makefiles

Command Line

  1. cmake .. -G "MinGW Makefiles"

CMake GUI

初次Configure时指定项目的generator。

选用MinGW Makefiles,使用默认编译器。

如果已经指定generator后,需要修改。可以清除CMake Cache后再次ConfigureFile->Delete Cache

PreLoad.cmake

CMake设置generator是在处理CMakeLists.txt之前的,因此不能通过在CMakeLists.txt中设置CMAKE_GENERATOR达到修改默认generator的作用。

可以在项目根目录添加PreLoad.cmake这样的文件实现预先修改配置,内容如下。

  1. set(CMAKE_GENERATOR "MinGW Makefiles" CACHE INTERNAL "" FORCE)

设置make

即使已为MinGW添加了环境变量,但是不能在命令行中直接使用make。gcc、g++、gfortran可以直接使用。

是因为在<安装路径>\MinGW\bin下,对应make的可执行程序名字为mingw32-make,在同目录下拷贝一份,重命名为make即可使用。

示例程序

CMake

以下为CMakeLists.txt文件内容,

  1. # name: exe_test
  2. # date: 2021/3/14
  3. #
  4. cmake_minimum_required(VERSION 3.3)
  5. project(exe_test CXX Fortran)
  6. add_executable(hello source/hello.cpp)
  7. add_executable(caller_cpp source/caller.cpp)
  8. add_executable(caller_fort source/caller.f90)

设置Fortran语言的一个小问题

  1. -->$ cmake ..
  2. -- The CXX compiler identification is GNU 9.3.0
  3. CMake Error: Could not find cmake module file: CMakeDetermineFORTRANCompiler.cmake
  4. CMake Error: Error required internal CMake variable not set, cmake may not be built correctly.
  5. Missing variable is:
  6. CMAKE_FORTRAN_COMPILER_ENV_VAR
  7. CMake Error: Error required internal CMake variable not set, cmake may not be built correctly.
  8. Missing variable is:
  9. CMAKE_FORTRAN_COMPILER
  10. ...

这个问题的原因在CMakeLists.txt中,是大小写敏感的,Fortran只应该使用首字母大写的形式。

  1. # project(exe_test CXX FORTRAN)
  2. project(exe_test CXX Fortran)

source/hello.cpp

  1. // name: hello.cpp
  2. // date: 2021/3/14
  3. //
  4. #include <iostream>
  5. using namespace std;
  6. int main()
  7. {
  8. cout << "Aloha!" << endl;
  9. return 0;
  10. }

source/caller.cpp

  1. // name: caller.cpp
  2. // date: 2021/3/14
  3. //
  4. #include <iostream>
  5. #include <string>
  6. #include <Windows.h>
  7. #include <tlhelp32.h>
  8. #include <process.h>
  9. using namespace std;
  10. void Launch(LPCTSTR lpApplicationName)
  11. {
  12. // additional information
  13. STARTUPINFO si;
  14. PROCESS_INFORMATION pi;
  15. // set the size of the structures
  16. ZeroMemory( &si, sizeof(si) );
  17. si.cb = sizeof(si);
  18. ZeroMemory( &pi, sizeof(pi) );
  19. // start the program up
  20. CreateProcess( lpApplicationName, // the path
  21. (char*)"", // Command line
  22. NULL, // Process handle not inheritable
  23. NULL, // Thread handle not inheritable
  24. FALSE, // Set handle inheritance to FALSE
  25. 0, // No creation flags
  26. NULL, // Use parent's environment block
  27. NULL, // Use parent's starting directory
  28. &si, // Pointer to STARTUPINFO structure
  29. &pi // Pointer to PROCESS_INFORMATION structure (removed extra parentheses)
  30. );
  31. cout << "process id: " << pi.dwProcessId << ", thread id: " << pi.dwThreadId << endl;
  32. // Close process and thread handles.
  33. CloseHandle( pi.hProcess );
  34. CloseHandle( pi.hThread );
  35. }
  36. int main(int argv, char* args[])
  37. {
  38. cout << "caller_cpp:" << endl;
  39. // 1.
  40. // 可以加路径,路径中应使用\\而非/
  41. // WinExec("hello.exe", SW_SHOW);
  42. // 2.
  43. // SHELLEXECUTEINFO shell = { sizeof(shell) };
  44. // shell.fMask = SEE_MASK_FLAG_DDEWAIT;
  45. // shell.lpVerb = "open";
  46. // shell.lpFile = "hello.exe";
  47. // shell.nShow = SW_SHOWNORMAL;
  48. // BOOL ret = ShellExecuteEx(&shell);
  49. // 3.
  50. // ShellExecuteA
  51. // ShellExecute(NULL, "open", "hello.exe", NULL, NULL, SW_SHOWDEFAULT);
  52. // 4.
  53. // system("hello.exe");
  54. // 5.
  55. Launch("hello.exe");
  56. // 6.
  57. // _execv("hello.exe", args);
  58. return 0;
  59. }

收集了多种方式,建议使用CreateProcess(),详细内容查阅Microsoft Docs。

source/caller.f90

  1. ! name: caller.f90
  2. ! date: 2021/3/14
  3. !
  4. PROGRAM Caller_fort
  5. PRINT *, "Caller_fort"
  6. ! Fortran 2008
  7. call execute_command_line ("hello.exe", wait=.false.)
  8. !
  9. call system("hello.exe")
  10. END

execute_command_lineFortran2008标准开始支持的函数。

参考资料

  1. cmake_ Selecting a generator within CMakeLists.txt - Stack Overflow
  2. Using cmake with fortran - Stack Overflow
  3. windows C_C++ 在一个程序中打开,关闭和监视其它的exe程序_lumanman_的博客-CSDN博客
  4. C++ 打开exe文件的方法(VS2008) - work hard work smart - 博客园
  5. C++ 中打开 exe 文件_楠木大哥的博客-CSDN博客
  6. C++程序中调用exe可执行文件_积累点滴,保持自我-CSDN博客_c++调用exe文件
  7. ShellExecuteA function (shellapi.h) - Win32 apps _ Microsoft Docs
  8. Creating Processes - Win32 apps _ Microsoft Docs
  9. _exec, _wexec Functions _ Microsoft Docs
  10. EXECUTE_COMMAND_LINE (The GNU Fortran Compiler)
  11. SYSTEM (The GNU Fortran Compiler)

原文链接:http://www.cnblogs.com/0xzhang/p/14623929.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号