在运行时生成可执行文件

3
好的,我想知道如何创建一个程序,它可以创建第二个程序(就像大多数压缩程序可以创建自解压缩文件一样,但这不是我需要的)。假设我有两个程序。每个程序都包含一个类。我将使用其中一个程序来修改并填充数据类。第二个文件也将是一个程序,它也有这个类,但是为空的,它的唯一目的是以特定方式访问此数据。我不知道,我在想如果特定类被序列化,然后“注入”到第二个文件中。但是怎么做呢?我发现修改已经编译的文件很有趣,尽管我从未能够进行没有错误的更改。我希望得到一些跨平台的C或C ++信息。我只接受另一种语言是C#。我不想使用编译器。

2
你有没有特别的原因不能在运行时从文件中加载数据(例如从CSV/XML等文件)? - Joe
2
gcc是一个能够创建其他程序的程序。 - mouviciel
5
“Grr...意味着”人类(以及其他有思维能力的生物,如果有的话)推断;数据、句子等则“暗示”。/ 学究式编辑模式 - dmckee --- ex-moderator kitten
4
请采用与你提到的自解压可执行文件相同的方式进行操作:它们不会在运行时生成新程序。 它们只是将同一份程序写入文件,并且只有在运行时加载程序的数据时才进行自定义。 - jalf
1
您想在运行时生成C、C++或C#可执行代码,而不使用编译器。目前为止,还没有合理的答案。投票关闭此问题,因为它“不是一个真正的问题”。 - David Thornley
显示剩余2条评论
7个回答

5
从零开始构建可执行文件很困难。首先,你需要为程序生成机器代码,然后你需要将这些代码封装在可执行文件中。这只有在你想编写一种语言的编译器时才显得过于繁琐。
这些生成自解压可执行文件的工具并不是真正从头开始创建可执行文件。它们已经预先生成了可执行文件,并且数据文件只是追加在其末尾。由于Windows可执行文件格式允许你在文件末尾放置数据,所以只需要关心“真正的可执行”部分(exe头告诉你它有多大-其余部分被忽略)。
例如,尝试生成两个自解压缩zip文件,并对它们进行二进制比较。你会发现它们的前X KB完全相同,不同的是剩余部分,这并不是一个可执行文件,只是数据。当文件被执行时,它会查找在文件末尾找到的内容(数据)并解压缩它。
请查看维基百科条目,转到外部链接部分深入了解: http://en.wikipedia.org/wiki/Portable_Executable 我只提到了Windows,但同样的原理适用于Linux。但是不要期望获得跨平台的结果,你必须针对每个平台重新实现它。我无法想象有什么比可执行文件更依赖于平台的东西了。即使你使用C#,你也必须生成本地存根,这在Windows(.net下)或Linux(Mono下)运行时是不同的。

很好。不过,需要指出的是,有Linux和Windows可执行文件... Linux只是不使用后缀名.exe。但这很有趣,我没有意识到他们做了一些如此简单的事情。这几乎像是某种作弊一样。但这基本上就是我想知道的。谢谢。 - Kelly Elton
嗯,为了纠正我所写的内容,我应该说“...比可执行文件更大”,而不是“...比可执行文件格式更大”。PE(Windows)实际上是COFF(Unix)的一个变体,但你有不同的运行时,在导入表中为OS API提供不同的符号等。所有这些东西都需要针对每个目标操作系统进行特定的实现。而且今天在类Unix操作系统中,ELF是一种更流行的格式,它与PE和COFF有很大的不同。 - Fabio Ceconello

3

你的程序生成数据后,是否需要将临时文件写入磁盘并调用编译器进行编译?或者这个问题是关于编写本地可执行文件格式的详细内容?


不幸的是,考虑到您不想要编译器,这是正确的答案,也是您在运行时获得可执行文件的唯一途径。 - Billy ONeal

3
很不幸,对于编译型语言例如C、C++、Java或C#,你不能像在解释型语言中(如PHP、Perl和ECMAscript)那样仅仅“运行”新代码。代码必须先进行编译,因此你需要一个编译器。这是无法避免的。
如果你需要在两个独立的EXE之间复制保存/恢复功能,那么最好的方法是创建一个静态库,该库在两个程序之间共享,或者创建一个DLL,在两个程序之间共享。这样,你只需编写一次代码,并且可以被任意数量的程序使用。
另一方面,如果你真的遇到了这种情况,我的主要问题是:你想通过这样做实现什么目标?即使在支持eval()等功能的语言中,自修改代码通常也是最糟糕和最容易出错的东西。它甚至比完全使用GOTO编写的程序还要糟糕。虽然有时候会用到自修改代码,但99%的情况下这是错误的方法。
希望能对你有所帮助 :)

关于你的第一段,请阅读我的编辑。我感激其余部分。谢谢。 - Kelly Elton

1
我曾经遇到过同样的问题,我认为 this 可以解决所有问题。你可以在那里放置任何代码,如果正确,它将在运行时生成第二个可执行文件。
--ADD--
简而言之,您有一些代码,可以硬编码并存储在第一个可执行文件的代码中,或者让其外部运行。然后,您运行它并编译上述代码。如果一切正常,您将在运行时获得第二个可执行文件-编译。所有这些都不需要任何外部库!

0

也许我读错了我找到的东西,但它似乎与问题无关。感谢提供这些链接,比有些人只说“使用某个函数”要好得多。哦,如果我已经完全了解那个函数了,我就不会问了 :p - Kelly Elton

0

您是否考虑将Lua或Python等脚本语言嵌入您的应用程序中?这将使您能够在运行时动态生成和执行代码。

来自wikipedia

动态编程语言是计算机科学中广泛使用的术语,用于描述一类高级编程语言,在运行时执行许多其他语言可能在编译期间执行(如果有的话)的常见行为。这些行为可以包括通过添加新代码、扩展对象和定义或修改类型系统来扩展程序,所有这些都在程序执行期间完成。这些行为可以在足够复杂的任何语言中模拟,但动态语言提供了直接的工具来利用它们。


我写了一个小脚本语言。谢谢你的回答,但请阅读我的编辑。 - Kelly Elton

0

根据你对程序的定义,自修改代码 可能会有所帮助。

基本上,你可以将代码写入内存中的某个位置,就像它是普通数据一样,并调用它。 通常这是一个不好的想法,但很有趣。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接