1. 如何禁止程序利用 ShellExecute 函數調用默認瀏覽器彈出廣告網頁窗口
不是很清楚shellexecute是什麼函數,使用文件選擇對話框通常都有個問題是,這個程序會修改默認的系統路徑,試試下面這樣創建:
CFileDialog fileDiaog(TRUE, NULL, NULL, OFN_NOCHANGEDIR);
不行的話就要使用GetCurrentDir和SetCurrentDir了。
你試試GetCurrentDir和SetCurrentDir這兩個函數呢?
2. 如何讓靜態庫中的可執行程序不調用的函數不鏈接進該可
nclude <stdio.h>#include "fun1.h"int main(int argc, const char *argv[]){ fun1_0(); printf("file:%s/tfunc:%s/n", __FILE__, __FUNCTION__); return 0;}
然後執行下面的命令:
gcc -c -ffunction-sections fun1.c ar -r libfun1.a fun1.o gcc -c -ffunction-sections main.c gcc main.o -L. -I. libfun1.a -Wl,--gc-sections -o main 或者 gcc main.o -L. -I. -lfun1 -Wl,--gc-sections -o main
3. 怎樣防止自己的程序調用的api函數被hook
對於程序員來講,API攔截技術是一種重要的基礎技術。這項技能為編寫某些工具軟體提供了可能,並可以大大提高我們對第三方應用程序的控制能力。不過,目前 API 攔截的技術資料往往局限於原理方面的論述,對於如何具體地編譯一個 API 攔截程序卻
4. 我在用一個程序。但是我一啟動就會調用ExitWindowsEx函數來關機 所以怎麼禁止ExitWindowsEx函數來關機
瑞星的系統內核加固可以設置拒絕關機或關機時詢問用戶,這時可以阻止.
除此之外,我能想到的編程解決辦法就只有hook系統了.
5. matlab如何避免使用for循環調用函數
V1 = 1:7;
V2 = 3:3:19;
V3 = 4:-1:0;
n = 3; % n 即為組數
Y = arrayfun(@(x) fit(['V' num2str(x)]),1:n,'un',false)
6. C++中,怎樣關閉正在運行的可執行程序,該調用什麼函數/////
exit(1);
7. 啟動keil5出現如圖警告,並且寫函數過程中,不會提示錯誤,求解決方法
Keil 編譯時出現錯誤和警告的總結
和C 編譯器錯誤信息中文翻譯
(1)L15 重復調用
***WARNING L15: MULTIPLE CALL TO SEGMENT
SEGMENT: ?PR?SPI_RECEIVE_WORD?D_SPI
CALLER1: ?PR?VSYNC_INTERRUPT?MAIN
CALLER2: ?C_C51STARTUP
該警告表示連接器發現有一個函數可能會被主函數和一個中斷服務程序(或者調用中斷服務程序的函
數)同時調用,或者同時被多個中斷服務程序調用。
出現這種問題的原因之一是這個函數是不可重入性函數,當該函數運行時它可能會被一個中斷打斷,從
而使得結果發生變化並可能會引起一些變數形式的沖突(即引起函數內一些數據的丟失,可重入性函數在任何時候
都可以被ISR 打斷,一段時間後又可以
運行,但是相應數據不會丟失)。
原因之二是用於局部變數和變數(暫且這樣翻譯,arguments,[自變數,變元一數值,用於確定程序或子
程序的值])的內存區被其他函數的內存區所覆蓋,如果該函數被中斷,則它的內存區就會被使用,這將導致其他函數
的內存沖突。
例如,第一個警告中函數WRITE_GMVLX1_REG 在D_GMVLX1.C 或者D_GMVLX1.A51 被定義,它被一個中斷
服務程序或者一個調用了中斷服務程序的函數調用了,調用它的函數是VSYNC_INTERRUPT,在MAIN.C 中。
解決方法:
如果你確定兩個函數決不會在同一時間執行(該函數被主程序調用並且中斷被禁止),並且該函數不佔
用內存(假設只使用寄存器),則你可以完全忽略這種警告。
如果該函數佔用了內存,則應該使用連接器(linker)OVERLAY 指令將函數從覆蓋分析(overlay
analysis)中除去,例如:
OVERLAY (?PR?_WRITE_GMVLX1_REG?D_GMVLX1 ! *)
上面的指令防止了該函數使用的內存區被其他函數覆蓋。如果該函數中調用了其他函數,而這些被調用在
程序中其他地方也被調用,你可能會需要也將這些函數排除在覆蓋分析(overlay analysis)之外。這種OVERLAY 指
令能使編譯器除去上述警告信息。
如果函數可以在其執行時被調用,則情況會變得更復雜一些。這時可以採用以下幾種方法:
1.主程序調用該函數時禁止中斷,可以在該函數被調用時用#pragma disable 語句來實現禁止中斷的目的。必
須使用OVERLAY 指令將該函數從覆蓋分析中除去。
2.復制兩份該函數的代碼,一份到主程序中,另一份復制到中斷服務程序中。
3.將該函數設為重入型。例如:
void myfunc(void) reentrant {
...
}
這種設置將會產生一個可重入堆棧,該堆棧被被用於存儲函數值和局部變數,用這種方法時重入堆
棧必須在STARTUP.A51 文件中配置。這種方法消耗更多的RAM 並會降低重入函數的執行速度。
(2)提示無M51 文件
編譯時候提示:
F:\...\XX.M51
File has been changed outside the editor, reload ?
------
解決方法:
重新生成項目,產生STARTUP.
1/9
A51 即可。
(3)L16 無調用
*** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS
SEGMENT: ?PR?_COMPARE?TESTLCD
說明:程序中有些函數例如COMPARE(或片段)以前(調試過程中)從未被調用過,或者根本沒
有調用它的語句。
這條警告信息前應該還有一條信息指示出是哪個函數導致了這一問題。只要做點簡單的調整就
可以。不理它也沒什麼大不了的。
解決方法:去掉COMPARE()函數或利用條件編譯#if …..#endif,可保留該函數並不編譯。
(4)L10 和L16"主程序名字寫錯(或無主程序)"
8. 請教C++ 如何退出當前調用函數,謝謝!
直接寫return ;就好了,不要括弧。
9. 編寫程序時,調用函數是怎麼回事
ibrary 即動態鏈接庫文件),是一種不能單獨運行的文件,它允許程序共享執行特殊任務所必需的代碼和其他資源
比較大的應用程序都由很多模塊組成,這些模塊分別完成相對獨立的功能,它們彼此協作來完成整個軟體系統的工作。可能存在一些模塊的功能較為通用,在構造其它軟體系統時仍會被使用。在構造軟體系統時,如果將所有模塊的源代碼都靜態編譯到整個應用程序 EXE 文件中,會產生一些問題:一個缺點是增加了應用程序的大小,它會佔用更多的磁碟空間,程序運行時也會消耗較大的內存空間,造成系統資源的浪費;另一個缺點是,在編寫大的 EXE 程序時,在每次修改重建時都必須調整編譯所有源代碼,增加了編譯過程的復雜性,也不利於階段性的單元測試。
Windows 系統平台上提供了一種完全不同的較有效的編程和運行環境,你可以將獨立的程序模塊創建為較小的 DLL 文件,並可對它們單獨編譯和測試。在運行時,只有當 EXE 程序確實要調用這些 DLL 模塊的情況下,系統才會將它們裝載到內存空間中。這種方式不僅減少了 EXE 文件的大小和對內存空間的需求,而且使這些 DLL 模塊可以同時被多個應用程序使用。Windows 自己就將一些主要的系統功能以 DLL 模塊的形式實現。
一般來說,DLL 是一種磁碟文件,以.dll、.DRV、.FON、.SYS 和許多以 .EXE 為擴展名的系統文件都可以是 DLL。它由全局數據、服務函數和資源組成,在運行時被系統載入到調用進程的虛擬空間中,成為調用進程的一部分。如果與其它 DLL 之間沒有沖突,該文件通常映射到進程虛擬空間的同一地址上。DLL 模塊中包含各種導出函數,用於向外界提供服務。DLL 可以有自己的數據段,但沒有自己的堆棧,使用與調用它的應用程序相同的堆棧模式;一個 DLL 在內存中只有一個實例;DLL 實現了代碼封裝性;DLL 的編制與具體的編程語言及編譯器無關。
在 Win32 環境中,每個進程都復制了自己的讀/寫全局變數。如果想要與其它進程共享內存,必須使用內存映射文件或者聲明一個共享數據段。DLL 模塊需要的堆棧內存都是從運行進程的堆棧中分配出來的。Windows 在載入 DLL 模塊時將進程函數調用與 DLL 文件的導出函數相匹配。Windows 操作系統對 DLL 的操作僅僅是把 DLL 映射到需要它的進程的虛擬地址空間里去。DLL 函數中的代碼所創建的任何對象(包括變數)都歸調用它的線程或進程所有。
調用方式:
1、靜態調用方式:由編譯系統完成對 DLL 的載入和應用程序結束時 DLL 卸載的編碼(如還有其它程序使用該 DLL,則 Windows 對 DLL 的應用記錄減1,直到所有相關程序都結束對該 DLL 的使用時才釋放它,簡單實用,但不夠靈活,只能滿足一般要求。
隱式的調用:需要把產生動態連接庫時產生的 .LIB 文件加入到應用程序的工程中,想使用 DLL 中的函數時,只須說明一下。隱式調用不需要調用 LoadLibrary() 和 FreeLibrary()。程序員在建立一個 DLL 文件時,鏈接程序會自動生成一個與之對應的 LIB 導入文件。該文件包含了每一個 DLL 導出函數的符號名和可選的標識號,但是並不含有實際的代碼。LIB 文件作為 DLL 的替代文件被編譯到應用程序項目中。
當程序員通過靜態鏈接方式編譯生成應用程序時,應用程序中的調用函數與 LIB 文件中導出符號相匹配,這些符號或標識號進入到生成的 EXE 文件中。LIB 文件中也包含了對應的 DL L文件名(但不是完全的路徑名),鏈接程序將其存儲在 EXE 文件內部。
當應用程序運行過程中需要載入 DLL 文件時,Windows 根據這些信息發現並載入 DLL,然後通過符號名或標識號實現對 DLL 函數的動態鏈接。所有被應用程序調用的 DLL 文件都會在應用程序 EXE 文件載入時被載入在到內存中。可執行程序鏈接到一個包含 DLL 輸出函數信息的輸入庫文件(.LIB文件)。操作系統在載入使用可執行程序時載入 DLL。可執行程序直接通過函數名調用 DLL 的輸出函數,調用方法和程序內部其 它的函數是一樣的。
2、動態調用方式:是由編程者用 API 函數載入和卸載 DLL 來達到調用 DLL 的目的,使用上較復雜,但能更加有效地使用內存,是編制大型應用程序時的重要方式。
顯式的調用:
是指在應用程序中用 LoadLibrary 或 MFC 提供的 AfxLoadLibrary 顯式的將自己所做的動態連接庫調進來,動態連接庫的文件名即是上面兩個函數的參數,再用 GetProcAddress() 獲取想要引入的函數。自此,你就可以象使用如同本應用程序自定義的函數一樣來調用此引入函數了。在應用程序退出之前,應該用 FreeLibrary 或 MFC 提供的 AfxFreeLibrary 釋放動態連接庫。直接調用 Win32 的 LoadLibary 函數,並指定 DLL 的路徑作為參數。LoadLibary 返回 HINSTANCE 參數,應用程序在調用 GetProcAddress 函數時使用這一參數。GetProcAddress 函數將符號名或標識號轉換為 DLL 內部的地址。程序員可以決定 DLL 文件何時載入或不載入,顯式鏈接在運行時決定載入哪個 DLL 文件。使用 DLL 的程序在使用之前必須載入(LoadLibrary)載入DLL從而得到一個DLL模塊的句柄,然後調用 GetProcAddress 函數得到輸出函數的指針,在退出之前必須卸載DLL(FreeLibrary)。
正因為DLL 有佔用內存小,好編輯等的特點有很多電腦病毒都是DLL格式文件。但不能單獨運行。
動態鏈接庫通常都不能直接運行,也不能接收消息。它們是一些獨立的文件,其中包含能被可執行程序或其它DLL調用來完成某項工作的函數。只有在其它模塊調用動態鏈接庫中的函數時,它才發揮作用。
dll和內存管理
在Win32中,DLL文件按照片段(sections)進行組織。每個片段有它自己的屬性,如可寫或是只讀、可執行(代碼)或者不可執行(數據)等等。
DLL代碼段通常被使用這個DLL的進程所共享;也就是說它們在物理內存中占據一個地方,並且不會出現在頁面文件中。如果代碼段所佔據的物理內存被收回,它的內容就會被放棄,後面如果需要的話就直接從DLL文件重新載入。
與代碼段不同,DLL的數據段通常是私有的;也就是說,每個使用DLL的進程都有自己的DLL數據副本。作為選擇,數據段可以設置為共享,允許通過這個共享內存區域進行進程間通信。但是,因為用戶許可權不能應用到這個共享DLL內存,這將產生一個安全漏洞;也就是一個進程能夠破壞共享數據,這將導致其它的共享進程異常。例如,一個使用訪客賬號的進程將可能通過這種方式破壞其它運行在特權賬號的進程。這是在DLL中避免使用共享片段的一個重要原因。
當DLL被如UPX這樣一個可執行的packer壓縮時,它的所有代碼段都標記為可以讀寫並且是非共享的。可以讀寫的代碼段,類似於私有數據段,是每個進程私有的並且被頁面文件備份。這樣,壓縮DLL將同時增加內存和磁碟空間消耗,所以共享DLL應當避免使用壓縮DLL。[1][2]
[3]找到DLL文件地址:C:\WINDOWS\system32\****.dll時出錯(****就是你的那個找不到的文件名)
開始--運行--msconfig--啟動--找到和你說的類似的選項****--取消勾--確定,然後
1,開始-運行-輸入:regedit,然後回車
2,選擇「我的電腦」,然後點擊「文件」-「導出」-隨便起個名字點「保存」。這樣做的目的是備份一下注冊表,以免誤操作後及時恢復。恢復的方法是,找到你剛才保存的文件,雙擊它,然後選擇「允許導入」即可。
3,選擇「我的電腦」,按F3鍵,然後輸入「****」,點擊「查找下一個」,找到後一定要核對是不是****.dll文件,因為你給的文件名不全,如果確認,對該項點「右鍵」選「刪除」。「此時可以輸入****.dll進行查找,結果出來後要看後面的數值部分,不能光看文件名稱,只要有****.dll在的文件不管它邊上還寫沒寫別的(如:****.dll,load),都要刪除!」
4,然後再按F3鍵-刪除,直到提示「沒有找到相應選項」為止。
5,重新啟動計算機,看看系統有沒有問題。
注,如果出現了其它嚴重問題,請恢復注冊表。
10. multiple call to segment怎麼解決
來自http://www.cnblogs.com/curiositywzk/archive/2011/12/25/2301090.html
***warning
l15:
multiple
call
to
segment
今天來說說***
warning
l15:
multiple
call
to
segment這個問題!
其實這個問題應該是引起注意的,有可能引起程序沖突,但是一般時候程序運行不會有問題,但是如果出來問題,那將會是很討厭的問題.
分析一下
產生這一警告的一個根源是:例如在主循環里調用了一個函數,而在中斷服務中,你又一次調用了同樣的函數。這樣當主循環運行到該函數中時,
一旦產生中斷,則在中斷里又再次調用該函數!而使得該子函數發生了重入,這時,經管概率很低,但是很可能出錯!這樣,編譯器就給出了警告!告訴你***
warning
l15:
multiple
call
to
segment
,表達的意思是發生了重入!字面意思自己理解去吧~~~
想要避免這種情況的方法
一.用reentrant使函數重入
關於reentrant的說明:
1,重入函數不能傳遞bit類型的參數和變數;
2,重入函數建立的是模擬堆棧區,所以不使用一般函數位於存儲模式默認空間的可覆蓋式堆棧,而是在同一空間從頂端另行分配一個非覆蓋式的重入堆棧。
small
默認空間是
data;
compact
默認空間是
pdata;
largr
默認空間是
xdata;
3,由於要保存參數和局部變數,所以會消耗很大的棧空間;盡量少用這種模式;
4、
在同一程序中可以定義和使用不同存儲器模式的重入函數,任意模式的重入函數不能調用不同存儲器模式的重入函數,但可以調用普通函數。
5、
實際參數可以傳遞給間接調用的重入函數。無重入屬性的間接調用函數不能包含調用參數。
二.如果空間多的話,可以定義兩個同功能的函數,分別在中斷和中斷外調用
別的方法沒研究出來,嘿嘿~~~對了
我建議用第二種方法好點,第一種有些限制,不爽~~
三.主程序調用該函數時禁止中斷。
可以在該函數被調用時用#pragma
disable語句來實現禁止中斷的目的。必須使用overlay指令將該函數從覆蓋分析中除去。
也可以用ea=1,ea=0來開關中斷
最後,warning
l15:
multiple
call
to
segment
這個問題必須注意,可能引起程序沖突,假設你用於自動化領域,則可能導致信號產生尖峰。
產生這一警告的一個根源是:你在主循環
里調用了一個函數(如aaa),而在中斷服務函數里,你用調用了這個函數(如aaa)。這樣當主循環運行到該函數中
是,一旦產生中斷,則在中斷里又再次調用該函數!這時,很可能出錯!
避免這種情況的方法很多:如,在進中斷的時候置需調用該函數的標志,而在主循環中調用該函數
分類:
keil
c51
curiosity