Windows下C++/Fortran调用.exe可执行文件

编程

目录

  • 软件环境
  • Windows下CMake编译配置
    • 设置项目的generator
      • Command Line
      • CMake GUI
      • PreLoad.cmake
    • 设置make
  • 示例程序
    • CMake
      • 设置Fortran语言的一个小问题
    • source/hello.cpp
    • source/caller.cpp
    • source/caller.f90
  • 参考资料

软件环境

# 操作系统 = Windows10

# 编译链工具 =

# gcc, g++, GNU Fortran (MinGW.org GCC Build-2) 9.2.0

# GNU Make 3.82.90 Built for i686-pc-mingw32

# GNU ld (GNU Binutils) 2.32

# CMake version 3.18.1

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

Windows下CMake编译配置

设置项目的generator

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

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

Command Line

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这样的文件实现预先修改配置,内容如下。

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

设置make

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

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

示例程序

CMake

以下为CMakeLists.txt文件内容,

# name: exe_test

# date: 2021/3/14

#

cmake_minimum_required(VERSION 3.3)

project(exe_test CXX Fortran)

add_executable(hello source/hello.cpp)

add_executable(caller_cpp source/caller.cpp)

add_executable(caller_fort source/caller.f90)

设置Fortran语言的一个小问题

-->$ cmake ..

-- The CXX compiler identification is GNU 9.3.0

CMake Error: Could not find cmake module file: CMakeDetermineFORTRANCompiler.cmake

CMake Error: Error required internal CMake variable not set, cmake may not be built correctly.

Missing variable is:

CMAKE_FORTRAN_COMPILER_ENV_VAR

CMake Error: Error required internal CMake variable not set, cmake may not be built correctly.

Missing variable is:

CMAKE_FORTRAN_COMPILER

...

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

# project(exe_test CXX FORTRAN)

project(exe_test CXX Fortran)

source/hello.cpp

// name: hello.cpp

// date: 2021/3/14

//

#include <iostream>

using namespace std;

int main()

{

cout << "Aloha!" << endl;

return 0;

}

source/caller.cpp

// name: caller.cpp

// date: 2021/3/14

//

#include <iostream>

#include <string>

#include <Windows.h>

#include <tlhelp32.h>

#include <process.h>

using namespace std;

void Launch(LPCTSTR lpApplicationName)

{

// additional information

STARTUPINFO si;

PROCESS_INFORMATION pi;

// set the size of the structures

ZeroMemory( &si, sizeof(si) );

si.cb = sizeof(si);

ZeroMemory( &pi, sizeof(pi) );

// start the program up

CreateProcess( lpApplicationName, // the path

(char*)"", // Command line

NULL, // Process handle not inheritable

NULL, // Thread handle not inheritable

FALSE, // Set handle inheritance to FALSE

0, // No creation flags

NULL, // Use parent"s environment block

NULL, // Use parent"s starting directory

&si, // Pointer to STARTUPINFO structure

&pi // Pointer to PROCESS_INFORMATION structure (removed extra parentheses)

);

cout << "process id: " << pi.dwProcessId << ", thread id: " << pi.dwThreadId << endl;

// Close process and thread handles.

CloseHandle( pi.hProcess );

CloseHandle( pi.hThread );

}

int main(int argv, char* args[])

{

cout << "caller_cpp:" << endl;

// 1.

// 可以加路径,路径中应使用\而非/

// WinExec("hello.exe", SW_SHOW);

// 2.

// SHELLEXECUTEINFO shell = { sizeof(shell) };

// shell.fMask = SEE_MASK_FLAG_DDEWAIT;

// shell.lpVerb = "open";

// shell.lpFile = "hello.exe";

// shell.nShow = SW_SHOWNORMAL;

// BOOL ret = ShellExecuteEx(&shell);

// 3.

// ShellExecuteA

// ShellExecute(NULL, "open", "hello.exe", NULL, NULL, SW_SHOWDEFAULT);

// 4.

// system("hello.exe");

// 5.

Launch("hello.exe");

// 6.

// _execv("hello.exe", args);

return 0;

}

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

source/caller.f90

! name: caller.f90

! date: 2021/3/14

!

PROGRAM Caller_fort

PRINT *, "Caller_fort"

! Fortran 2008

call execute_command_line ("hello.exe", wait=.false.)

!

call system("hello.exe")

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)

以上是 Windows下C++/Fortran调用.exe可执行文件 的全部内容, 来源链接: utcz.com/z/519540.html

回到顶部