Q&A°Ô½ÃÆÇ¿¡
BCB·Î ¸¸µç DLLÀ» VC++¿¡¼ »ç¿ëÇÒ¶§
DLL¿¡¼ TThreadÀÇ SynchronizeÇÔ¼ö¸¦ ¾µ¶§ÀÇ ¹®Á¦Á¡¿¡ ´ëÇØ
Áú¹®¿¡ ´äÇØÁÖ°í ÀÚ¼¼ÇÑ ¼³¸íÀ» ÆÁ/°Á °Ô½ÃÆÇ¿¡ ¿Ã¸°´Ù°í Çߴµ¥¿ä..
http://cbuilder.borlandforum.com/impboard/impboard.dll?action=read&db=bcb_qna&no=60086
ã¾Æº¸´Ï Á¦ Ä«Æä(http://cafe.naver.com/bcbmaster/)¿¡ ÀÌ¹Ì ¿¹Àü¿¡ ¿Ã·Á³õÀº ±ÛÀÌ Àֳ׿ä
http://cafe.naver.com/bcbmaster/1297
Ä«Æä¿¡ ¿Ã¸° ±Û ¿ø¹®À» ±×´ë·Î copy-pasteÇÕ´Ï´Ù.
//-----------------------------------------------------------------------------------------
°¡²û ¸ðµâÀ» ºÐ¸®Çϱâ À§ÇØ Dll·Î ¸¸µå´Â °æ¿ì°¡ ÀÖ´Ù.
Dll¿¡¼ VCLÀ» »ç¿ëÇÒ°æ¿ì ÁÖÀÇÇÒÁ¡ÀÌ ¿©·¯°¡Áö°¡ Àִµ¥...
±×Áß¿¡ Çϳª Dll³»ÀÇ Thread¿¡¼ SynchronizeÇÔ¼ö »ç¿ë½Ã
Synchronize ÇÔ¼ö°¡ Á¦´ë·Î µ¿ÀÛÇÏÁö ¾Ê´Â °æ¿ì¿¡ ´ëÇØ ¾ê±âÇϰíÀÚ ÇÑ´Ù.
¿À´Ã µ¨¸¶´ç¿¡ Dll¿¡¼ CPort»ç¿ë½Ã RxChar À̺¥Æ®°¡ ¹ß»ýÇÏÁö ¾Ê´Â´Ù´Â Áú¹®ÀÌ ¿Ã¶ó¿Ô¾ú´Ù.
ÂüÁ¶ http://www.delmadang.com/community/bbs_view.asp?bbsNo=17&bbsCat=0&st=&keyword=&indx=415729&keyword1=&keyword2=&page=1
°ü·ÃÇÏ¿© ¿øÀÎÀ» ã¾Æº» °á°ú
¿øÀÎÀº Dll³»ÀÇ Thread¿¡¼ SynchronizeÇÔ¼ö¿¡ ÀÖ¾ú´Ù.
[Synchronize ÇÔ¼ö µ¿ÀÛ ¿ø¸®]
¸ÕÀú SynchronizeÇÔ¼ö°¡ ¾î¶»°Ô µ¿ÀÛÇÏ´ÂÁö »ìÆì º¸°Ô½À´Ï´Ù.
´ÙÀ½Àº TThreadÀÇ Synchronize ÇÔ¼öÀÔ´Ï´Ù.
procedure TThread.Synchronize(Method: TThreadMethod);
class procedure TThread.Synchronize(ASyncRec: PSynchronizeRecord);
1 . ¸ÕÀú TThreadMethod¸¦ ÆÄ¶ó¸ÞÅÍ·Î ¹Þ´Â Synchronize ÇÔ¼ö¿¡¼
SynchronizeRecord ±¸Á¶Ã¼°Ô °ü·Ã parameter¸¦ ¼³Á¤ÇÑÈÄ¿¡
2. class procedure ÀÎ TThread.Synchronize ¸¦ È£ÃâÇÕ´Ï´Ù.
class procedure TThread.Synchronize(ASyncRec: PSynchronizeRecord);
var
SyncProc: TSyncProc;
begin
if GetCurrentThreadID = MainThreadID then
ASyncRec.FMethod
else
begin
{$IFDEF MSWINDOWS}
SyncProc.Signal := CreateEvent(nil, True, False, nil);
try
{$ENDIF}
{$IFDEF LINUX}
FillChar(SyncProc, SizeOf(SyncProc), 0); // This also initializes the cond_var
{$ENDIF}
EnterCriticalSection(ThreadLock);
try
if SyncList = nil then
SyncList := TList.Create;
SyncProc.SyncRec := ASyncRec;
SyncList.Add(@SyncProc);
SignalSyncEvent;
if Assigned(WakeMainThread) then
WakeMainThread(SyncProc.SyncRec.FThread); //¿©±â¼PostMessage(Application.Handle,WM_NULL...
{$IFDEF MSWINDOWS}
LeaveCriticalSection(ThreadLock);
try
WaitForSingleObject(SyncProc.Signal, INFINITE);
finally
EnterCriticalSection(ThreadLock);
end;
{$ENDIF}
{$IFDEF LINUX}
pthread_cond_wait(SyncProc.Signal, ThreadLock);
{$ENDIF}
finally
LeaveCriticalSection(ThreadLock);
end;
{$IFDEF MSWINDOWS}
finally
CloseHandle(SyncProc.Signal);
end;
{$ENDIF}
if Assigned(ASyncRec.FSynchronizeException) then raise ASyncRec.FSynchronizeException;
end;
end;
procedure TThread.Synchronize(Method: TThreadMethod);
begin
FSynchronize.FThread := Self;
FSynchronize.FSynchronizeException := nil;
FSynchronize.FMethod := Method;
Synchronize(@FSynchronize);
end;
3. À§ Äڵ忡 º¸¸é WakeMainThread ÇÔ¼ö¿¡¼
Application.Handle¿¡ PostMessage·Î WM_NULLÀ» º¸³½´Ù.
WakeMainThread(SyncProc.SyncRec.FThread); //¿©±â¼PostMessage(Application.Handle,WM_NULL...
4. ApplicationÀÇ WindowProc¿¡¼ WM_NULL¸Þ¼¼Áö¸¦ ¹Þ´Â ºÎºÐÀ» »ìÆìº¸¸é...
¾Æ·¡´Â TApplication.WndProc ÇÔ¼ö ÄÚµåÀÌ´Ù.
´ëºÐÀÇ Äڵ带 »ý·«Çϰí WM_NULL ¸Þ¼¼Áö°¡ ¿Ã°æ¿ì CheckSynchronize ¶ó´Â ÇÔ¼ö¸¦ È£ÃâÇÏ¿´´Ù.
procedure TApplication.WndProc(var Message: TMessage);
....
begin
try
with Message do
case Msg of
.....
WM_NULL:
CheckSynchronize;
else
Default;
end;
except
HandleException(Self);
end;
end;
5. ´ÙÀ½Àº CheckSynchronize ÇÔ¼öÀÌ´Ù.
LocalSyncList ¸®½ºÆ®¿¡ ÀÖ´Â Synchronize ÇÔ¼ö Á¤º¸¸¦ Çϳª¾¿ °¡Á®¿Í¼ ½ÇÇàÇϰí ÀÕ´Ù.
½ÇÇàÇÏ°í ³µÚ¿¡ SetEvent(SyncProc.signal); ·Î Synchronize¸¦ È£ÃâÇÑ Thread¸¦ wake½ÃÄÑ ÁØ´Ù.
function CheckSynchronize(Timeout: Integer = 0): Boolean;
var
SyncProc: PSyncProc;
LocalSyncList: TList;
begin
if GetCurrentThreadID <> MainThreadID then
raise EThread.CreateResFmt(@SCheckSynchronizeError, [GetCurrentThreadID]);
if Timeout > 0 then
WaitForSyncEvent(Timeout)
else
ResetSyncEvent;
LocalSyncList := nil;
EnterCriticalSection(ThreadLock);
try
Integer(LocalSyncList) := InterlockedExchange(Integer(SyncList), Integer(LocalSyncList));
try
Result := (LocalSyncList <> nil) and (LocalSyncList.Count > 0);
if Result then
begin
while LocalSyncList.Count > 0 do
begin
SyncProc := LocalSyncList[0];
LocalSyncList.Delete(0);
LeaveCriticalSection(ThreadLock);
try
try
SyncProc.SyncRec.FMethod; //½ÇÁ¦ SynchronizeÇÔ¼ö ½ÇÇà
except
SyncProc.SyncRec.FSynchronizeException := AcquireExceptionObject;
end;
finally
EnterCriticalSection(ThreadLock);
end;
{$IFDEF MSWINDOWS}
SetEvent(SyncProc.signal);
{$ENDIF}
{$IFDEF LINUX}
pthread_cond_signal(SyncProc.Signal);
{$ENDIF}
end;
end;
finally
LocalSyncList.Free;
end;
finally
LeaveCriticalSection(ThreadLock);
end;
end;
-------------------------------------------------------------------------------------------------
[Dll¿¡ ¾²·¹µå¿¡¼ SynchronizeÇÔ¼ö »ç¿ëÀÇ ¹®Á¦ µÇ´Â °æ¿ì´Â?]
dll¿¡ ÀÖ´Â ¾²·¹µå¿¡¼ SynchronizeÇÔ¼ö »ç¿ë¿¡ ¹®Á¦°¡ µÇ´Â °æ¿ì°¡ ¾î¶²°æ¿ì Àϱî?
±×°ÍÀº ´Ù¸§¾Æ´Ñ
ù° . Delphi ¶Ç´Â CBuilder·Î ¸¸µç DllÀ» °°Àº ¹öÁ¯ÀÇ Delphi³ª CBuilder·Î ¸¸µç exe¿¡¼ »ç¿ëÇÏÁö ¾Ê´Â°æ¿ì
µÑ° . DllÀ̳ª Exe¸ðµÎ °°Àº¹öÁ¯ÀÇ Delphi³ª CBuilder·Î ¸¸µç °æ¿ì¶ó ÇÏ´õ¶óµµ
ÄÄÆÄÀϽà Runtime-Package¸¦ »ç¿ëÇÏÁö ¾ÊÀº °æ¿ì µîÀÌ ÀÖ´Ù.
½Ç·Ê)
1) µ¨¸¶´çÀÇ Áú¹®¿¡¼¿Í °°ÀÌ CPort°°Àº serialÅë½Å ¼ö½Å À̺¥Æ®¿¡ ¹®Á¦°¡ »ý±ä´Ù.
2) ¶Ç´Â delphi/cbuilder ÀÇ ±âº» tcp/ip socketÀÎ TServerSocket/TClientsocketÀÇ ¼ö½ÅÀ̺¥Æ®¿¡µµ ¹®Á¦°¡ »ý±ä´Ù.
TServerSocket/TClientsocket Àº non-blocking¼ÒÄÏÀ¸·Î data¼ö½Å½Ã Synchronize ÇÔ¼ö·Î
¸ÞÀξ²·¹µå¿¡¼ À̺¥Æ®¸¦ ¹ß»ý½Ã۱⠶§¹®ÀÌ´Ù.
3) ±âŸ À§¿Í ºñ½ÁÇѰæ¿ì´Â ÀÌ·ç ¼öµµ¾øÀÌ ¸¹À»°ÍÀÌ´Ù.
[¹®Á¦ÀÇ ¿øÀÎ]
ÀÌÁ¦ ¹®Á¦ÀÇ ¿øÀÎÀ» »ìÆìº¸ÀÚ
¾Õ¿¡ SynchronizeÀÇ µ¿ÀÛ¿ø¸®¸¦ ÀÚ¼¼È÷ ¼³¸íÇÑ ÀÌÀ¯µµ ¿©±â¿¡ ÀÖ´Ù.
À§¿¡ SynchronizeÀÇ µ¿ÀÛ¿ø¸®¸¦ º¸¸é
WakeMainThreadÇÔ¼ö¿¡¼ ´ÙÀ½°ú °°ÀÌ Application.Handle·Î WM_NULL ¸Þ¼¼Áö¸¦ PostMessage·Î º¸³½´Ù.
procedure TApplication.WakeMainThread(Sender: TObject);
begin
PostMessage(Handle, WM_NULL, 0, 0);
end;
±×·±µ¥ DLLÀÇ °æ¿ì¿¡ Application.HandleÀÌ NULL ¶Ç´Â nil À̶ó´Âµ¥ ÀÖ´Ù.
´ÙÀ½Àº TApplicationŬ·¡½ºÀÇ »ý¼ºÀÚ ÇÔ¼öÀÌ´Ù.
constructor TApplication.Create(AOwner: TComponent);
... »ý·«
begin
inherited Create(AOwner);
.... »ý·«
if not IsLibrary then CreateHandle;
... »ý·«
end;
À§ Äڵ帣 º¸¸é not IsLibrary Áï DLLÀÌ ¾Æ´Ñ EXEÀÎ °æ¿ì¿¡¸¸ CreateHandleÀ» È£ÃâÇÑ´Ù.
Áï Dll¿¡¼´Â CreateHandle ÇÔ¼ö°¡ È£ÃâµÇÁö ¾Ê°í Application.HandleÀÌ NULLÀÌ´Ù.
Application.HandleÀÌ NULLÀÌ´Ï ¾Æ¹«¸® PostMessage·Î º¸³»µµ ¸Þ¼¼Áö¸¦ ¹ÞÀº HandleÀÌ ¾øÀ¸´Ï
Synchronize °¡ µ¿ÀÛÇÏÁö ¾Ê´Â °ÍÀÌ´Ù.
[ÇØ°á¹æ¹ý]
ù° . dll ¹× exeµÑ´Ù Runtime-Package ¸¦ »ç¿ëÇÑ´Ù.
Áï Dll ¹× exeµÑ´Ù runtime-package¸¦ »ç¿ëÇÑ´Ù´Â °ÍÀº?
runtime-package¸¦ »ç¿ëÇÏÁö ¾ÊÀ¸¸é
exe¿¡¼ »ç¿ëÇÏ´Â Application°´Ã¼¿Í dll¿¡¼ »ç¿ëÇÏ´Â Application°´Ã¼°¡ ´Ù¸¥ ³ðÀÌ µÈ´Ù.
exe/dllµÑ´Ù runtime-package¸¦ »ç¿ëÇÑ´Ù´Â ¶æÀº
VCLxx.bpl À» µ¿ÀûÀ¸·Î LoadPakageÇÏ¿©¼ dll°ú exe¿¡¼ °°Àº vclxx.bplÀ» »ç¿ëÇÏ°Ô µÈ´Ù.
ÇÏÁö¸¸ ¸¸¾à µÑÁß¿¡ ÇÑÂÊÀÌ¶óµµ runtime-package¸¦ »ç¿ëÇÏÁö ¾Ê°ÔµÇ¸é
µÑÁß ÇÑÂÊÀº static-linkµÈ vcl -lib¸¦ »ç¿ëÇÏ°Ô µÇ°Ô µÈ´Ù.
À̰æ¿ì dll¿¡ ÀÖ´Â ¾²·¹µå¿¡¼ Synchronize ¹®Á¦ »Ó¸¸ ¾Æ´Ï¶ó ¸Å¿ì ¸¹Àº ¹®Á¦¸¦ ¾ß±â ½ÃŲ´Ù.
µÑ° . Dll¿¡¼ Application->CreateHandle(); À» ¸í½ÃÀûÀ¸·Î È£ÃâÇØÁØ´Ù.
À§¿¡ ¼³¸íÇßµíÀÌ Application->HandleÀº Application->CreateHandle(); ÇÔ¼ö¿¡¼ »ý¼ºµÈ´Ù.
¸í½ÃÀûÀ¸·Î Application->CreateHandle(); À» È£ÃâÇØÁÙ°æ¿ì PostMessage·Î ¸Þ¼¼Áö¸¦ º¸³»°í ¹ÞÀ»
À©µµ¿ì HandleÀÌ »ý¼ºµÇ¹Ç·Î ¹®Á¦°¡ ÇØ°áµÇ´Â °ÍÀÌ´Ù.
¼Â°. delphi³ª CBuilder·Î¸¸ project¸¦ ÇÒ°æ¿ì DLL ´ë½Ã BPLÀ» »ç¿ëÇÏ´Â ¹æ¹ýµµ ÀÖ´Ù.
BPLÀº delphi¿¡¼ »ç¿ëÇÏ´Â dll·Î½á bpl·Î ¸ðµâÀ» ¸¸µé¸é Runtim-package¹× static-link ½Ã¿¡ ¾Ë¾Æ¼
¸µÅ©ÇØÁØ´Ù. ±×·¡¼ exe³ª bpl¿¡¼ °°Àº vclxx.bpl À» »ç¿ëÇÏ°Ô µÇ¹È·Î ¹®Á¦°¡ ÇØ°áµÈ´Ù.
¸¸¾à DllÀÌ °°Àº ¹öÁ¯ÀÇ delphi³ª CBuilder°¡ ¾Æ´Ñ ÇÁ·Î±×·¥À¸·Î ¸¸µç exe¿¡¼ »ç¿ëÇÒ ¸ñÀûÀ̶ó¸é
µÎ¹øÂ° ¹æ¹ý Application->CreateHandle();À» »ç¿ëÇÏ±æ ±ÇÇÑ´Ù.
±×·³...
|