Re: [問題] 產生的執行檔無法開啟指定檔案

看板C_and_CPP (C/C++)作者 (閉上眼的魚)時間13年前 (2013/01/01 22:31), 編輯推噓6(6032)
留言38則, 8人參與, 最新討論串3/3 (看更多)
我簡單敘述一下這是什麼情況好了,下面三個線索都是原 po 自己敘述的 線索一: code寫好了成功編譯,按下IDE的"build and run"也沒問題可以執行 線索二: → donvito:cmd window很快的的閃過一句 "輸入的檔案錯誤" 就關掉了 12/31 23:34 → donvito:就只有這樣而已 大概0.1秒 簡直考驗我的動態視力 12/31 23:35 線索三: 我把release底下的exe檔複製貼上到project所在的資料夾層就可以執行了 很合理可以猜測, donvito 對於檔案路徑特性並不熟悉。 假設專案為 D:\HelloWorld,裡面放了 demo.bmp 然後在 src 裡面寫了 FILE * fp = fopen("demo.bmp", "rb"); if(fp==NULL) { printf("Open fail\n"); return EXIT_FAILURE; } /* what ever... */ fclose(fp); return EXIT_SUCCESS; 然後由於 demo.bmp 只存在於 D:\HelloWorld 裡面,所以開啟會正常, 再加上 Code::Blocks 在結束的時候會自動加上 pause, 計時, 所以看得到正常結果。 接下來 donvito 又跑到 D:\HelloWorld\bin\Release 裡面的 HelloWorld.exe 執行, 這時候 HelloWorld.exe 在當前路徑找不到 demo.bmp ,所以噴出在 code 裡面寫的 "Open fail" 字句,也由於該判斷沒加上 pause 等任何暫停指令, 所以看起來就在考動態視力。 言歸正傳.. ※ 引述《donvito (CryFather)》之銘言: : → purincess:current directory不對? 01/01 00:44 : 您猜對了... : 我把release底下的exe檔複製貼上到project所在的資料夾層就可以執行了... : (這個project含有自己寫的header) 這是因為,當你寫下 fopen("demo.bmp", "rb"); 的時候, 會到「執行檔的當前路徑」去搜尋 demo.bmp 這個檔案, 所以你第二次怎樣都搜尋不到。 那為什麼在 Code::Blocks ide 下可以找到呢? 其實任何 IDE 都找得到,在用 IDE 開發的時候, 他會把環境設定為專案本身的目錄,以上例而言,也就是你用 IDE 時, 會到 D:\HelloWorld 裡面找 demo.bmp; 但退出 IDE ,單獨用 .exe 執行時候,就會在「和 exe 同一目錄」底下搜尋 demo.bmp : 小怒伯我去年(code陪我跨年...有點淒涼)才踏入程式領域 : 我猜是code blocks不是把.o全部寫成一個exe而是先存放在obj\release 這句話對,正常而言,一個 .c(.cpp) 會配合一個 .o,這個動作叫「編譯 compile 」。 ( 當然我跳過了前置處理這過程 ) : 執行的時候才去從當前directory底下obj\release找出來link在一起? 這句話不對,這個動作是「連結」做的事,從數個 .o 產生一個 .exe, 叫做連結 (link),你也可以只連結產生一個執行檔,但不去執行它。 : (所以我如果想要輸出一個可以直接執行的exe要調整什麼設定呢@@?) 這裡的「一個可以直接執行的 exe 」必須定義一下,如果你是想要連那個 demo.bmp 都不要有的話,不可能!這樣你的程式就不該有 fopen 之類型的動作。 然後推文裡說的「靜態連結」,指的是,有些情況是,你的執行檔、輸入檔都有, 在你的電腦裡面都可以執行,但把這份執行檔、輸入檔拿到別人電腦就不能執行, 這時候大多是因為,你的執行檔需要「某些動態連結檔 (dll)」,但別人的電腦裡 面沒有! 你可以有兩種解決方式,一種是在別人的電腦裡面安裝這些動態連結檔, 這樣你的執行檔就可以執行,而且執行檔會比較小; 另一種方式是在編譯的時候,對編譯器下指令,選擇「靜態連結」,這樣 執行檔會比較大,但可以保證在沒有「某些動態連結檔」的情況下,別人 的電腦也可以正常執行。 : 關於這方面有沒有前輩可以推薦什麼書? (原文的也無所謂 : 感謝! 路徑的問題 http://edisonx.pixnet.net/blog/post/89099733 1. 絕對 / 相對路徑 編譯器 / IDE 的問題 □ [分享] Windows 下架構 C/C++ 簡易 IDE #1EU6-1Ld (C_and_CPP) 書 : 程式設計師的自我修養 http://ppt.cc/iSL( ---------------------- 這裡我要補充一下,我沒記錯的話, gcc 系列的 (Dev-Cpp , Code::Blocks) 似乎是不用特定選靜態連結, 我記得以前開發給客戶時,用 gcc 送的最後也沒特別指定,client 就可直接執行, ( 所以其實是 IDE 預設是用 static link ? ) 有誤的話也請不吝更正。 -- ~ 這輩子與神手無緣 我只好當神獸了 ~ -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 180.177.76.161

01/01 22:33, , 1F
呃... 我在上面有補述 fopen不是一開始執行的動作
01/01 22:33, 1F

01/01 22:33, , 2F
我也知道要讀取的檔案必須放同一個路徑
01/01 22:33, 2F

01/01 22:34, , 3F
不過link那部分就真的不熟 轉C::B才第一次遇到
01/01 22:34, 3F
suhorng:?? 所以之前說 "C::B" 產生的 .o 副檔名, 不是動態連結? 01/01 22:34

01/01 22:35, , 4F
(我之前是指說shared lib副檔名好像不會是 .o?是嗎?)
01/01 22:35, 4F

01/01 22:34, , 5F
其實連圖檔也包到同一個檔案還是有可能的啦, 只是這樣就
01/01 22:34, 5F

01/01 22:35, , 6F
不能用 fopen 了
01/01 22:35, 6F

01/01 22:36, , 7F
.o 是 GCC 的 object 檔案, Code::Blocks 是用 MinGW 所
01/01 22:36, 7F

01/01 22:36, , 8F
以 object 檔也是叫 .o
01/01 22:36, 8F
嗯,正確的說我猜應該也是下載 Code::Blocks-with-MinGW,object 是 .o 。 包圖檔到同一檔案的話... 我想到的是全塞到 stack ,不過好像.. 是蠻想見識一下就是了。

01/01 22:40, , 9F
@donvito, 我覺得你沒看懂我的敘述,你的問題很明顯是餵給
01/01 22:40, 9F

01/01 22:41, , 10F
fopen 時的檔案,沒給對「路徑」,你可試著輸入「絕對路徑」
01/01 22:41, 10F

01/01 22:41, , 11F
我第二點說閃過0.1秒 是os根本不給我進入這個exe
01/01 22:41, 11F

01/01 22:42, , 12F
怎麼可能執行fopen的動作
01/01 22:42, 12F
可能我猜錯,抱歉。若真如此,我想放 code 真較佳,另外我覺得可以先搜一下 有沒有在 source code 裡出現這句 「輸入的檔案錯誤」,我怎麼看都不認為, 這串中文字會是 compiler 會跳出來的東西。 總之我實在覺得,linker 機率真的不大,特別都是在你的電腦裡面執行的。              ** 推文放齊 *** ※ 編輯: EdisonX 來自: 180.177.76.161 (01/01 22:51)

01/01 22:47, , 13F
01/01 22:47, 13F

01/01 22:48, , 14F
如果我把src貼到bin\release則又可以執行了...
01/01 22:48, 14F

01/01 22:49, , 15F
這時也還沒執行到fopen的步驟 (btw 一直都有system("pause
01/01 22:49, 15F

01/01 22:51, , 16F
把 colormap.bin 刪掉呢?
01/01 22:51, 16F

01/01 22:53, , 17F
喔 幹...........是colormap的問題..........我真他媽蠢
01/01 22:53, 17F

01/01 22:54, , 18F
因為是引用給好的函式去讀colormap 所以fopen藏在一行
01/01 22:54, 18F

01/01 22:55, , 19F
我沒看到的地方..........
01/01 22:55, 19F

01/01 22:55, , 20F
樓上真激動 XD
01/01 22:55, 20F

01/01 22:56, , 21F
對不起各位陪我耍蠢<(_ _)>
01/01 22:56, 21F

01/01 22:57, , 22F
不過我很好奇為什麼C::B輸出的exe大小是devc++的近1/10
01/01 22:57, 22F

01/01 23:03, , 23F
一天的問題又解決了~~~
01/01 23:03, 23F

01/01 23:03, , 24F
不過 windows 中 dynamic load 的好像都是 .dll?
01/01 23:03, 24F

01/01 23:03, , 25F
新的一年一開始就解決了舊的問題 大吉大利~~
01/01 23:03, 25F

01/01 23:04, , 26F
話說回來 其實我前幾個推文問你有沒有用到別人家library
01/01 23:04, 26F

01/01 23:04, , 27F
(講錯了是上文的推文) 也包含有沒有用別人的函式啦~"~
01/01 23:04, 27F

01/01 23:05, , 28F
@suhorng : 對, 但 C::B 裡面還是在用 .a(lib) / .so(dll)
01/01 23:05, 28F

01/01 23:06, , 29F
因為我很自以為地篤定給好header沒有用到fopen...囧
01/01 23:06, 29F

01/01 23:09, , 30F
了解 謝謝E大
01/01 23:09, 30F

01/01 23:09, , 31F
另外, 要直接塞一個 raw binary 檔進去可以看
01/01 23:09, 31F

01/01 23:09, , 32F

01/01 23:10, , 33F
embedding-file-executable-aka-hello-world-version-5967
01/01 23:10, 33F

01/01 23:10, , 34F
(兩行都是網址)
01/01 23:10, 34F

01/01 23:10, , 35F
補一下誤,使用 MinGW32 系列,還是可以產生 dll
01/01 23:10, 35F

01/01 23:17, , 36F
s 大給的 linker 有趣,幫縮 http://ppt.cc/rCER
01/01 23:17, 36F

01/01 23:51, , 37F
太熱心了 所以推
01/01 23:51, 37F

01/03 21:06, , 38F
原po隔空抓藥高手XD
01/03 21:06, 38F
文章代碼(AID): #1GulCrN0 (C_and_CPP)
文章代碼(AID): #1GulCrN0 (C_and_CPP)