我想將一堆C++文件編譯爲原始機器代碼,並用C編寫的平臺相關啓動器運行它(類似於fread(buffer,1,len ,文件); a =((* int(*)(int))buffer)(b);)在Windows和Linux上相同的二進制代碼(x86)
如何告訴g ++輸出原始代碼?
函數調用會起作用嗎?我怎樣才能使它工作?
我認爲linux和windows的調用約定有所不同。這是一個問題嗎?我該如何解決它?
編輯:我知道PE和ELF阻止直接啓動的可執行文件。但那是我的首發。
我想將一堆C++文件編譯爲原始機器代碼,並用C編寫的平臺相關啓動器運行它(類似於fread(buffer,1,len ,文件); a =((* int(*)(int))buffer)(b);)在Windows和Linux上相同的二進制代碼(x86)
如何告訴g ++輸出原始代碼?
函數調用會起作用嗎?我怎樣才能使它工作?
我認爲linux和windows的調用約定有所不同。這是一個問題嗎?我該如何解決它?
編輯:我知道PE和ELF阻止直接啓動的可執行文件。但那是我的首發。
有一個(相對)簡單的方法來實現這一點,這就是所謂的「位置獨立代碼」。請參閱您的編譯器文檔。
這意味着您可以將一些源代碼編譯爲二進制文件,無論您在何處放置它,都會執行該二進制文件。如果你在一個文件和mmap()中有這樣一段x86二進制代碼(或者相當於windows),可以從Linux和Windows上調用它。
已經提到的限制當然依然存在 - 也就是說,二進制代碼必須限制自己使用在兩個平臺上都相同的調用約定/可以在兩個平臺上表示(對於32位x86,這將通過參數EAX中的堆棧和返回值),當然代碼必須是完全獨立的 - 不需要DLL函數調用,因爲解決這些問題是依賴於系統的,也不需要系統調用。
即:
然後mmap()該文件,初始化函數指針和(* myblob)(someArgs)可能會做。
如果你使用的是gcc,「-freestanding -nostdinc -fPIC」選項應該給你大部分關於前兩個的東西,然後使用objdump從ELF對象文件中提取二進制blob。
做這樣的事情將是相當複雜的。這不僅僅是發出cpu命令的問題,編譯器依賴於許多將鏈接到代碼中的庫。這些庫必須在運行時匹配,否則將無法工作。
例如,STL庫是一系列模板和庫函數。編譯器將內聯一些構造併爲其他人調用該庫。它必須是完全相同的圖書館才能工作。現在
,在理論上可以儘量避免使用任何圖書館,只是在基本面寫的,但即使有編譯器可以使它們是如何工作,參與什麼類型的數據比對,調用約定,等
假設不要誤解我的意思,它可以工作。查看WINE項目以及Linux上使用的其他Windows本地驅動程序。我只是說這不是您可以快速輕鬆地完成的事情。
最好是在每個平臺上重新編譯。
本帖子中有太多無關緊要的內容 – KevinDTimm 2010-11-18 16:21:15
從理論上講,這是可以實現的。然而,沿途有這麼多問題,這對於任何事情來說都不是一個真正的實用解決方案。
你有鏈接嗎?我以爲我可以傳遞一個函數指針給包含的代碼,指向一個平臺相關的函數。像系統調用一樣。 – dkreuter 2010-11-18 16:25:24
這是可以實現的前提是你有WINE可用你的Linux系統上。否則,可執行文件格式的差異將阻止您在Linux上運行Windows代碼。
爲什麼不看看葡萄酒?這是爲了在Linux上使用Windows可執行文件。另一個解決方案是使用Java或.NET字節碼。
您可以在Linux上運行.NET可執行文件(需要單聲道運行時)
也看看昂納的objconv(拆卸,改裝PE可執行ELF等) http://www.agner.org/optimize/#objconv
不會發生 - 雙完全不同的目標文件格式 – KevinDTimm 2010-11-18 16:14:51
儘管我沒有資格回答,但看起來似乎應該可以這樣。如果我可以編寫不依賴任何標準庫的代碼,就好像對於嵌入式系統,它應該可以在任何x86芯片上運行,不是嗎? – sdg 2010-11-18 16:22:43
看到這個問題http://superuser.com/questions/209703/why-wont-windows-exes-work-on-linux - 簡短的回答ELF(Linux)與PE(Windows) – KevinDTimm 2010-11-18 16:22:58