原創 DLL編寫經驗總結(一)使DLL支援多執行緒
最近用Delphi編寫DLL比較多,總結幾條經驗方便以後回顧。
需求背景:DLL介面自身是向主調方提供服務,考慮到主調方的不定性以及響應速度問題,需要支援多執行緒。
實現思路:DLL在初次載入或者被喚醒的時候會呼叫DLLMain函式(Delphi的Main函式頭已被隱藏,實際上就是主檔案中的Begin End),觸發DLL_Process_Attach事件。可用全域性變數DLLProc來處理觸發的事件所呼叫的函式。
DLL在退出的時候會呼叫DLLMain函式(Delphi的Main函式頭已被隱藏,實際上就是主檔案中的Begin End),觸發DLL_Process_Detach事件。可用全域性變數ExitProc
Delphi原始碼如下:
var
OldExitProc:pointer;
begin
DLLProc:[email protected];//由於DLLProc原事件已經執行完成,此處可以不再儲存原事件
MyDLLHandler(DLL_Process_Attach);//執行自定義方法
OldExitProc:=ExitProc;//暫存退出後處理函式地址
ExitProc:[email protected]; //讓系統呼叫自定義函式處理事情,在MyExitProc中需要賦值回來。
end.
為了限制不同時執行某些關鍵區域,使用Delphi Windows下的CriticalSection
在DLL對映時建立,在介面中運用Enter、Leave,在退出時銷燬
var FSection: TRTLCriticalSection;//定義一個關鍵區域用於執行緒互斥執行 //關鍵區域進出 procedure Enter(OutType:string); begin _log('Enter FSection',OutType); EnterCriticalSection(FSection); end; procedure Leave(OutType:string); begin _log('Leave FSection',OutType); LeaveCriticalSection(FSection); end; //關鍵區域使用 procedure MyDLLHandler(Reason: integer); begin case Reason of DLL_Process_Attach: //整個DLL的初始化程式碼 begin _log('DLL_Process_Attach', 'FSection'); InitializeCriticalSection(FSection); end; DLL_Process_Detach: //整個DLL的善後程式 begin DeleteCriticalSection(FSection); _log('DLL_Process_Detach', 'FSection'); end; DLL_Thread_Attach: //當主叫端開始一個Thread時 begin _log('DLL_Thread_Attach', 'FSection'); StartMyThreadsAndWaitBegin(); end; DLL_Thread_Detach: //當主叫端終止一個Thread時 begin _log('DLL_Thread_Detach', 'FSection'); StopMyThreadsAndWaitEnd(); end; end; end; procedure MyExitProc; begin _log('MyExitProc','FSection'); ExitProc:=OldExitProc;//恢復退出的事件 end; procedure StartMyThreadsAndWaitBegin(); begin _log('StartMyThreadsAndWaitBegin','FSection'); Exit; end; procedure StopMyThreadsAndWaitEnd(); begin _log('StopMyThreadsAndWaitEnd','FSection'); Exit; end;
關鍵區域在介面中運用舉例:
{
created by: JustinYang 2016-09-23
function: 托盤解綁
Param in: Ahandle窗體控制代碼, serverIP 訪問伺服器IP,serverPort 伺服器埠,s_TrayID 托盤編號,i_TrayRFID 托盤RFID
Param Out: 整型 -1 網路異常;-2 托盤編號長度不對; -3 RFID大小異常; 1 解綁成功 0 解綁不成功
}
function upFreeTray(AHandle: THandle; serverIP: PChar; serverPort: integer; s_TrayID:PChar; i_TrayRFID:Int64): integer; export; stdcall;
var
p_serverIP: string;
P_serverPort,j: Integer;
tOld,tNew:TDateTime;
trayID:string;
trayRFID:Int64;
hw:Integer;
begin
try
try
Enter('FSection');
j:=-1;
result:=j;
_log(' IP:'+serverIP+' Port:'+IntToStr(serverPort),'upFreeTray');
if Length(string(s_TrayID)) <3 then s_TrayID :='';
_log(' Begin upFreeTray IP:'+serverIP+' Port:'+IntToStr(serverPort)+' Tray:'+IntToStr(i_TrayRFID)+':'+s_TrayID+' at '+DateTimeToStr(Now),'upFreeTray');
CoInitialize(nil);
Application.handle := AHandle;
trayID:=string(s_TrayID);
trayRFID:=i_TrayRFID;
if (Trim(trayID)='') and (trayRFID <= 0) then
begin
_log(' End upFreeTray '+IntToStr(trayRFID)+':'+trayID+' at '+ DateTimeToStr(Now) + ' result:'+IntToStr(j),'upFreeTray');
result:=0;
Exit;
end;
DllDataModule := TDllDataModule.Create(Application);
p_serverIP := string(serverIP);
if serverPort <= 0 then
P_serverPort := 8095
else
P_serverPort := serverPort;
DllDataModule.Channel.Host := string(p_serverIP);
DllDataModule.Channel.Port := P_serverPort;
except
on e:Exception do
begin
j := -1;//網路連線失敗
_log('When dll access network occours:'+e.Message,'upFreeTray');
Exit;
end;
end;
try
j := ((DllDataModule.RemoteService as INewService).upFreeTray(trayID, trayRFID));
if j > 0 then j := 1;
except
on e:Exception do
begin
j:=-4;
_log('When dll access server occours:'+e.Message,'upFreeTray');
Exit;
end;
end;
finally
DllDataModule.free;
result:=j;
_log(' End upFreeTray '+IntToStr(i_TrayRFID)+' '+s_TrayID+' at '+ DateTimeToStr(Now) + ' result:'+IntToStr(j),'upFreeTray');
CoUninitialize;
Leave('FSection');
end;
end;
相關推薦
原創 DLL編寫經驗總結(一)使DLL支援多執行緒
最近用Delphi編寫DLL比較多,總結幾條經驗方便以後回顧。需求背景:DLL介面自身是向主調方提供服務,考慮到主調方的不定性以及響應速度問題,需要支援多執行緒。實現思路:DLL在初次載入或者被喚醒的時候會呼叫DLLMain函式(Delphi的Main函式頭已被隱藏,實際上就
Redis面試題(一): Redis到底是多執行緒還是單執行緒?
0. redis單執行緒問題 單執行緒指的是網路請求模組使用了一個執行緒(所以不需考慮併發安全性),即一個執行緒處理所有網路請求,其他模組仍用了多個執行緒。 1
C++11併發程式設計(一)——初始C++11多執行緒庫
1 前言 C++11標準在標準庫中為多執行緒提供了元件,這意味著使用C++編寫與平臺無關的多執行緒程式成為可能,而C++程式的可移植性也得到了有力的保證。 在之前我們主要使用的多執行緒庫要麼
java_web項目開發經驗總結(一)
從數據 簡單 處理 開發 事務 傳輸 記錄 承載 基礎上 web項目就像一個動態的記事本,功能很強大,你最初的項目功能調研越給力,項目所能發揮的作用也就越給力。這是因為web網絡的強聯系性,大家都可以通過訪問到自己想要訪問的頁面,頁面裏既可以承載信息,也可以承載做事情的
HTTP介面自動化經驗總結(一)介面自動化簡述
講介面自動化之前,先說說介面測試的優勢。 以下是我總結的幾點。 介面測試位於功能測試前,發現bug早修改早成本低。 介面測試的引數會比開發的引數更豐富,得到的結果更快更多。 能發現大部分介面未校驗的引數,省去我們功能測試輸入太多數值。
2015異常問題解決方案經驗總結(一)
1. could not find java.dll C:\Users\admin>java Error: Registry key 'Software\JavaSoft\JavaRuntime has value '1.6', but '1.8' is r
美團外賣開放平臺對接經驗總結(一)
兩個月的時間,在除官方文件之外的資源極其匱乏的條件下,專案組群策群力完成了美團和餓了麼的外賣開放平臺對接,在這裡對團隊成員表示感謝,也把專案中填過的坑,淌過的河分享給大家。這注定是一篇受眾極少的文章,但是希望能夠對需要的人有所幫助。 如果能回到兩個月前,我會告訴剛剛開始開發這個專案的團隊,開發之
Netty 入門(一):基本元件與執行緒模型
Netty 的學習內容主要是圍繞 TCP 和 Java NIO 這兩個點展開的,後文中所有的內容如果沒有特殊說明,那麼所指的內容都是與這兩點相關的。由於 Netty 是基於 Java NIO 的 API 之上構建的網路通訊框架,Java NIO 中的幾個元件,都能在 Netty 中找到對應的封裝。下面我們
Windows執行緒(二)最簡單的多執行緒建立
一段最簡單的多執行緒建立程式碼如下: #include <stdio.h> #include <process.h> #include <Windows.h> #define THREAD_NUM 5 unsigned int __stdca
python學習總結(一),第一個python程序的編寫
程序代碼 spa 編碼 結構 編輯 下載地址 utf 修改編碼 general 1. python是一種解釋性,編譯型,互動型的語言,面向對象,動態數據類型的高級程序設計語言。 1.1 交互式:意味著可以在一個提示符直接交互執行你寫的程序。 1.2 解釋型:意味著開發過程中
HTTP介面自動化經驗總結(四)Okhttp3 介面測試用例編寫
經過前面幾次的分享,我們已經有了方法和結果,那麼這篇文章我們就來寫測試用例。 首先我們新建一個TestNG class,名字為APITest,繼承我們的依賴方法DependeicesMethod 1.get介面測試 //測試Get方法,其餘校驗請自行新增 @Test
QT 總結(一)(1.某位設1或0 2.載入dll、lib庫 3.char * 轉換為 wchar_t * 4.textBrowser 顯示亂碼 追加 5.checkBox的使能)
今天寫小程式遇到的問題,做個小總結: 1.如何對某一位置0或者置1? 寫成巨集,方便移植 #define setbit(x,y) x|=(1<<y) //將X的第Y位置1 #define clrbit(x,y) x&=~(1<<y) //將
去BAT,你應該要看一看的面試經驗總結(轉)
unique lock lose 單鏈表 一個數 協議頭 art 進制 操作系統原理 來源微信公眾號『easyserverdev』 http://mp.weixin.qq.com/s/UZljzFMjobo1wzCguY7NDg 說下我的面試經驗吧,都是親身經歷,
項目優化經驗分享(一)數據自己主動匹配
als 主動 options option reg shee total tomat 功能 從今天開始。我將和大家分享一下近期經手項目的優化經驗。今天我們分享的內容是:自己主動匹配! 引言: 輸入框數據自己主動匹配大家應該非常熟悉,當我們在使用百度或go
文檔總結(一)——文檔的概述
理解 需要 軟件需求 是否 研究 strong 開發項目 問題 項目開發 寫完文檔後,本來想寫一篇具體的文檔的總結的,後來看大家都寫的具體文檔總結,於是我就想:我還是寫一些跟大家不一樣的東西吧。 所以,我就說說我對各個文檔的宏觀理解吧。
salesforce零基礎學習(七十二)項目中的零碎知識點小總結(一)
gin 不同 grant dmi ima -m ron 角色 com 項目終於告一段落,雖然比較苦逼,不過也學到了好多知識,總結一下,以後當作參考。 一.visualforce標簽中使用html相關的屬性使用 曾經看文檔沒有看得仔細,導致開發的時候走了一些彎路。還好得到
HDMI調試經驗分享(一)—— 基於KC705的example實現
alt 如果 追蹤 分享 生成 必須 還需要 pro 註意 在KC705的平臺上,實現HDMI的example有兩個,xapp1287,xapp1291。其中1291偏復雜。 因為我沒有HDCP的license,使用xapp1287的tcl生成
OpenGL在MFC中的使用總結(一)——基本框架
palette 接受 white 要求 無效 結構 del 一次 是你 項目中要畫3D顯示的模型,於是要用到OpenGL,加上是在MFC中,並且是在MFC中的ActiveX中使用。再並且鑒於他們程序主框架的設定。常規的方法還不一定能實現。所以還是查過不少資料,在此一一總
操作系統基礎知識總結(一)
一個 快速 會有 處理死鎖 b2c fcm 死鎖 空間 存儲系統 1. 進程和線程的區別 進程 進程,即正在運行的程序,程序從硬盤載入到內存就變成進程。進程是資源的擁有者,每個進程都擁有著自己的內存空間與多個線程。 線程 線程是指令的執行者,是計算機執行指令的基本單元,一個
react native 知識點總結(一)
修改 ltp 組件 改變 set 覆蓋 sta 一個 個數 一、關於react native 版本的升級 參照文檔:http://reactnative.cn/docs/0.45/upgrading.html react-native -v