如何使 Linux 命令行程序在 Windows 中工作

How to make a linux command-line program work in windows?

本文关键字:Windows 工作 程序 何使 Linux 命令行      更新时间:2023-10-16

我是编程的初学者,我一直在 Ubuntu 中用 C/C++ 工作。当我告诉 cin/cout/cerr 或 printf/scanf 或从命令行获取参数时,这一切都发生在 Ubuntu 的 linux 终端上。

现在,如果我想运行这些相同的程序(非常简单的程序,初学者级别)并在Windows中运行它们,如何从Windows命令行运行它们?我之前参加的课程让我们下载cygwin来模拟Windows中的linux命令行,但是如果我想从普通的windows命令行运行程序怎么办?这可能吗,是否需要修改软件?

您可以从 Linux 交叉编译适用于 Windows 的程序。

在 Ubuntu 上,流程基本上是这样的:

sudo apt-get install wine mingw32 mingw32-binutils mingw32-runtime

i586-mingw32msvc-g++ -o myProgram.exe myProgram.cpp

很简单,对吧?谷歌的"ubuntu交叉编译Windows",那里有大量的信息。

完全一样。你运行cmd并编写命令(几乎)与在 Linux 中完全相同。

例如,如果你构建你的程序来program,你会像这样在 Linux 中运行它:

./program --option1 -o2 file1 file2

在Windows中,首先您必须使输出具有.exe后缀,然后在cmd中编写:

program.exe --option1 -o2 file1 file2

基本上说,cmd是Windows的终端。它远不如Linux终端,但这就是您无需安装其他软件即可获得的全部内容。


cin/cout/cerrprintf/scanf/fprintf(stderr, ...)使用在Linux和Windows中定义的标准C预打开文件stdinstdoutstderr。从Windows终端(cmd)运行应用程序后,您会看到与Linux终端完全相同的输入/输出。I/O 重定向也非常相似。

cincout,以及printfscanf,在Windows中的工作方式与在Linux中的工作方式大致相同。 (我很确定cerr也是如此,但那个我不是100%确定。 不过,至少,它在那里并且有效。 最大的区别是 Windows 在运行程序之前通常不会扩展通配符(如 *.txt );在大多数情况下,您必须自己执行此操作。

基本上,只要应用程序不使用特定于Linux或GCC的任何内容,您就可以使用您喜欢测试的任何编译器在目标计算机上重新编译它。

如果您不想重新编译...井。。。祝你好运。 甚至Cygwin也不会运行原生Linux二进制文件。 你需要一个装有Linux的虚拟机。

好吧,如果你的程序是可移植的,并且不使用任何特定于Linux的功能,你必须从Windows上的源代码编译它,使其在Windows上运行。

您需要Windows的GCC工具链才能做到这一点,您可以从TDM-GCC主页获得。它的MinGW内部和安装程序允许您选择要安装的功能以及要安装的目标目录。它还将自身添加到 Windows 路径,以便编译器命令可从 shell 提示符下使用。

我必须定期进行交叉编译,它对我来说没有任何问题。如果您的项目使用的是生成文件,则必须进行一项更改。对于目标二进制文件(例如 linux 中的 <target>.out),您必须编辑 Makefile 并将其重命名为 <target>.exe,以便它在命令行上运行。如果您不使用 Makefiles 而只是执行gcc <file.c>,则默认情况下会生成a.exe(类似于 Linux 中的a.out)。

假设你有这个程序代码,你想在UNIX和Windows上运行:

#include <stdio.h>
int main()
{
    printf("Hin");
    return 0;
}

当你在UNIX shell中键入一个命令时,它将是这样的。

/usr/home/bobby# gcc main.c
/usr/home/bobby# ./a.out
Hi
/usr/home/bobby#

在Windows上,您必须首先选择开发环境/编译器。 不用像Cygwin这样的东西,你可以安装Windows SDK或Visual Studio(尽管如果是后者,你可能只想在GUI中开发)。

Start -> Run -> cmd /k ""C:Program Files (x86)Microsoft Visual Studio 10.0VCvcvarsall.bat"" x86
C:Windowssystem32>cd c:bobby
C:bobby>cl main.c
C:bobby>main.exe
Hi
C:bobby>

当 C 程序被编译成可执行文件时,这是以系统依赖的方式完成的。在Ubuntu上使用ELF格式,在Windows上使用PE。

当您启动进程时,将读取 ELF 或 PE,给出有关如何分配内存以及将进程的各个部分放入虚拟内存表中的位置的说明/映射。此外,它链接到动态加载的库,已经在物理内存中,它与使用相同库的其他进程共享。或者,如果动态库不存在,则加载它们。(Linux .so, Windows .dll)。如果它有静态库,这些库将被分配和链接(Linux .a,Windows .lib)。- 非常简化。

内存限制等是从以前的过程中继承的。

环境变量被放入进程的运行环境中。这是路径、参数等。然后main()被添加到堆栈并调用。

现在在调用main之前发生的一切都以及如何解决链接等,以及许多其他事情,都取决于系统。这就是为什么根本无法在Windows上运行在Linux上编译的可执行文件的原因。

使用cygwin只是创建一个虚拟环境,其中这些链接等是相同的并且会起作用。一个创建 ELF 环境。

要使其链接到本机Windows命令行,必须针对Windows进行编译。在这个问题上,我看到已经有很多答案了。

ELF 和 PE 与不同的系统一样,处理环境变量等的方式也不同。这些是什么等等,即文件扩展的处理方式不同。但是,两个正在运行的进程都有默认流,如 stderrstdoutstdin 。但是在 C 代码下面,它们是不一样的。

这就像驾驶柴油车与汽油车。很多东西都是一样的,但在引擎盖下有很多事情是不同的。

请注意,即信号在Windows上的处理方式不同。

相关文章: