2010-11-18 74 views
2

我想將一堆C++文件編譯爲原始機器代碼,並用C編寫的平臺相關啓動器運行它(類似於fread(buffer,1,len ,文件); a =((* int(*)(int))buffer)(b);)在Windows和Linux上相同的二進制代碼(x86)

如何告訴g ++輸出原始代碼?

函數調用會起作用嗎?我怎樣才能使它工作?

我認爲linux和windows的調用約定有所不同。這是一個問題嗎?我該如何解決它?

編輯:我知道PE和ELF阻止直接啓動的可執行文件。但那是我的首發。

+0

不會發生 - 雙完全不同的目標文件格式 – KevinDTimm 2010-11-18 16:14:51

+0

儘管我沒有資格回答,但看起來似乎應該可以這樣。如果我可以編寫不依賴任何標準庫的代碼,就好像對於嵌入式系統,它應該可以在任何x86芯片上運行,不是嗎? – sdg 2010-11-18 16:22:43

+2

看到這個問題http://superuser.com/questions/209703/why-wont-windows-exes-work-on-linux - 簡短的回答ELF(Linux)與PE(Windows) – KevinDTimm 2010-11-18 16:22:58

回答

6

有一個(相對)簡單的方法來實現這一點,這就是所謂的「位置獨立代碼」。請參閱您的編譯器文檔。

這意味着您可以將一些源代碼編譯爲二進制文件,無論您在何處放置它,都會執行該二進制文件。如果你在一個文件和mmap()中有這樣一段x86二進制代碼(或者相當於windows),可以從Linux和Windows上調用它。

已經提到的限制當然依然存在 - 也就是說,二進制代碼必須限制自己使用在兩個平臺上都相同的調用約定/可以在兩個平臺上表示(對於32位x86,這將通過參數EAX中的堆棧和返回值),當然代碼必須是完全獨立的 - 不需要DLL函數調用,因爲解決這些問題是依賴於系統的,也不需要系統調用。

即:

  1. 你需要的位置無關的代碼
  2. 您必須創建自包含的代碼,而無需任何外部依賴
  3. 您必須從目標文件的機器代碼。

然後mmap()該文件,初始化函數指針和(* myblob)(someArgs)可能會做。

如果你使用的是gcc,「-freestanding -nostdinc -fPIC」選項應該給你大部分關於前兩個的東西,然後使用objdump從ELF對象文件中提取二進制blob。

1

相同的可執行文件無法在Windows和Linux上運行。

你編寫你的代碼平臺是獨立的(STL,Boost & Qt可以幫忙),然後在Linux上用G ++編譯輸出一個linux-binary,在windows平臺上用編譯器編譯。

編輯:另外,也許這兩個職位可能會幫助您:

One

Two

+0

是什麼讓這兩個平臺不兼容?兩者都使用x86。 – dkreuter 2010-11-18 16:16:42

+1

x86是一組指令集架構,與可執行文件和操作系統的結構無關。我已經通過其他一些關於跨平臺編程的答案更新了我的文章。 – 2010-11-18 16:17:58

0

做這樣的事情將是相當複雜的。這不僅僅是發出cpu命令的問題,編譯器依賴於許多將鏈接到代碼中的庫。這些庫必須在運行時匹配,否則將無法工作。

例如,STL庫是一系列模板和庫函數。編譯器將內聯一些構造併爲其他人調用該庫。它必須是完全相同的圖書館才能工作。現在

,在理論上可以儘量避免使用任何圖書館,只是在基本面寫的,但即使有編譯器可以使它們是如何工作,參與什麼類型的數據比對,調用約定,等

假設不要誤解我的意思,它可以工作。查看WINE項目以及Linux上使用的其他Windows本地驅動程序。我只是說這不是您可以快速輕鬆地完成的事情。

最好是在每個平臺上重新編譯。

+0

本帖子中有太多無關緊要的內容 – KevinDTimm 2010-11-18 16:21:15

2

從理論上講,這是可以實現的。然而,沿途有這麼多問題,這對於任何事情來說都不是一個真正的實用解決方案。

  • 系統調用格式是完全不相容
  • DEP將阻止執行代碼作爲數據
  • 內存佈局不同
  • 您需要有效地動態「重新鏈接」的代碼,然後才能運行它。
  • ...等等...
+0

你有鏈接嗎?我以爲我可以傳遞一個函數指針給包含的代碼,指向一個平臺相關的函數。像系統調用一樣。 – dkreuter 2010-11-18 16:25:24

-1

這是可以實現的前提是你有WINE可用你的Linux系統上。否則,可執行文件格式的差異將阻止您在Linux上運行Windows代碼。

1

爲什麼不看看葡萄酒?這是爲了在Linux上使用Windows可執行文件。另一個解決方案是使用Java或.NET字節碼。

您可以在Linux上運行.NET可執行文件(需要單聲道運行時)

也看看昂納的objconv(拆卸,改裝PE可執行ELF等) http://www.agner.org/optimize/#objconv

相關問題