我是一名编程初学者,我一直在Ubuntu的C / C ++中工作。 当我告诉cin / cout / cerr或者printf / scanf或者从命令行获取参数时,这一切都发生在Ubuntu的linuxterminal上。
现在,如果我想运行这些相同的程序(非常简单的程序,初学者级别)并在Windows中运行它们,我如何从Windows命令行运行它们? 我以前的课程让我们下载cygwin来模拟windows的linux命令行,但是如果我想从普通的windows命令行运行程序呢? 这是可能的,是否需要修改软件?
您可以从Linux交叉编译Windows程序。
在Ubuntu上,进程基本上是这样的:
sudo apt-get install wine mingw32-binutils mingw32-runtime
…
i586-mingw32msvc-g ++ -o myProgram.exe myProgram.cpp
很简单,对吧? 谷歌的“Ubuntu交叉编译窗口”,那里有很多信息。
完全一样。 你运行cmd
然后写出命令(几乎),就像在Linux中一样。
例如,如果你构建你的程序来program
,你可以像下面这样在Linux中运行它:
./program --option1 -o2 file1 file2
在Windows中,首先必须使输出具有.exe
后缀,然后在cmd
写入:
program.exe --option1 -o2 file1 file2
基本上说, cmd
是Windows的终端。 它远远不如Linux终端,但这将是所有你没有安装额外的软件。
cin
/ cout
/ cerr
和printf
/ scanf
/ fprintf(stderr, ...)
使用在Linux和Windows中定义的标准C预打开文件stdin
, stdout
和stderr
。 一旦从Windows的终端( cmd
)运行应用程序,就会像在Linux终端中那样看到输入/输出。 I / O重定向也非常类似。
cin
和cout
以及printf
和scanf
在Windows中的工作方式与在Linux中的工作方式大致相同。 (我很确定cerr
也是这样做的,但是那个我并不是100%肯定的,但至少在那里是可行的)。最大的区别是Windows通常不会扩展通配符*.txt
)在运行你的程序之前; 在大多数情况下你必须自己去做。
基本上,只要应用程序不使用任何特定于Linux或GCC的任何东西,就可以使用任何想要测试的编译器,在目标机器上重新编译它。
如果你不想重新编译…好吧…祝你好运。 即使Cygwin也不会运行本机Linux二进制文件。 你需要一个带有Linux的虚拟机。
那么,如果你的程序是可移植的,并且没有使用任何特定于Linux的特性,你将不得不在Windows上从源代码编译,使其在Windows上工作。
你需要GCC工具链来做到这一点,你可以从TDM-GCC主页获得。 它的MinGW内部和安装程序允许您选择要安装的功能以及安装的目标目录。 它还将自身添加到Windows路径中,以便编译器命令可以在shell提示符下使用。
我必须定期进行交叉编译,对我来说没有任何问题。 如果您的项目使用Makefiles,则必须进行一项更改。 对于目标二进制文件,比如linux中的<target>.out
,你必须编辑你的Makefile文件并将其重命名为<target>.exe
以便它在命令行上运行。 如果你没有使用Makefiles,而只是执行gcc <file.c>
a.exe
gcc <file.c>
,则a.exe
是默认生成的(类似于Linux中的a.out
)。
假设你有在UNIX和Windows上运行的程序代码:
#include <stdio.h> int main() { printf("Hi\n"); 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.0\VC\vcvarsall.bat"" x86 C:\Windows\system32>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也有不同的处理环境变量的方式等。这些都是如此,即文件扩展的处理方式是不同的。 但是,两个正在运行的进程都具有stderr
, stdout
和stdin
等默认流。 但是在C代码下面 ,它们是不一样的。
这就像驾驶柴油车和汽油车一样。 很多是相同的,但在引擎盖下相当多的事情是不同的。
请注意,即在Windows上处理信号的方式不同。