S/W 개발/Embarcadero2007.12.06 10:24

"for loop실행 중 Timer Event가 제대로 작동하나요?"

for loop가 약 30분 정도 돌아가야 되는데(기계제어 프로그램이기 때문에 for loop내에서 여러조건이 만족되어야 for loop내에서 다음 단계(step)로 넘어감) 이 과정중에 Timer Event를 사용할 필요가 있습니다. 즉 For Loop내에서 단계(step)가 진행될 때마다 global Variable이 변하게 되는데 이 때 이벤트를 걸어 다른 작업(Com2 Port를 통해 순간적으로 수신/전송을 해야 됨)을 해야 되기 때문이거든요. 그런데 for loop내에서 이 다른작업이라는 놈을 넣어니 최초 한번만 실행 되고 그 이후에는 반응이 없더라구요. 그래서 Timer event를 이용하여 일정간격으로 이 다른작업이라는 놈을 실행되도록 했더니 되긴 되는데 제대로 되지 않더군요. 즉 Global Variable은 계속 바뀌는데 Timer Event 함수내에서 이 Global 변수를 추적해 보니까 Timer함수내로 이 변수가 제대로 넘어오지 않더군요. (이하생략)


>> 답변 : 지나가는사람 님 ( bcbdn C++Builder Q&A 14815번 )

Timer의 경우는 그런상태가 벌어지는 경우가 많습니다.
저도 비슷한 문제로 여러가지로 테스트를 해보았는데...
윈98 계열의 경우는 그러한 상태가 일어나는 경우가 상당히 많고.. NT 계열은 그나마 좀 낮습니다.
(98은 마우스로 캡션바를 드래그 & 드롭하는 경우에도 Timer는 멈춥니다.)
그렇지만.. NT라도 제대로 제어를 하기 위해서는 스레드는 필수입니다.

>> 추가 : for loop나 while문을 계속 돌리고 싶은 경우 빠져나오는 조건이 명확하지 않다면 Thread를 쓰시는 편이 시스템 전체가 다운되는 현상을 방지할 수 있습니다.
Thread는 File > New > Thread Object 이러한 과정을 생성하면 되구요. 예를 들면 아래와 같이 생성할 수도 있습니다.

>> 참고

@ Execute
쓰레드 실행시에 실행 코드를 가지기 위한 순수 가상 메쏘드를 제공한다
(원형) virtual void __fastcall Execute(void) = 0;
(상세) 쓰레드 실행시 실행되어질 코드의 포함하고 실행하기위해 쓰인다. 이곳에서 쓰레드를 빠져나갈 조건을 체크한다.
CreateSuspended = false 라면 Create, CreateSuspended = true 라면 쓰레드를 생성 후에
Resume이 호출되었을 때 쓰레드는 실행한다.

(주의) 다른 오브젝트의 properties와 methods에서 직접적으로 쓰레드의 Execute를 사용하지 말라. 대신, procedure를 나눠서 Synchronize 메쏘드의 인자로써 procedure를 사용하라.


@ Synchronize
주요 VCL 쓰레드 호출 Executes method

(원형) typedef void __fastcall (__closure *TThreadMethod)(void);
       void __fastcall Synchronize(TThreadMethod &Method);

(상 세) Synchronize는 주 VCL 쓰레드를 사용하기위해 실행되어지는 메쏘드에만 호출되어야하기 때문에, 멀티-쓰레드에는 사용되지 말아야 한다. 쓰레드 호출이 안전할지 확실하지 않다면, 주 VCL 쓰레드를 거쳐서 Synchronize 메쏘드를 호출해라.
Execution 쓰레드는 주 VCL 쓰레드안에서 메쏘드가 실행될 동안에는 정지되어 있다.
(주의) critical section이나 multi-read exclusive-write synchronizer에서 사용되는 불안정한 메쏘드를 보호할 수 있다.

@ Priority
쓰레드 프로세스에서 상대적인 스케줄링 우선순위
(원형) enum TThreadPriority {tpIdle, tpLowest, tpLower, tpNormal, tpHigher, tpHighest, tpTimeCritical};
       __property TThreadPriority Priority = {read=GetPriority, write=SetPriority,nodefault};

(상세) Priority는 쓰레드 스케줄링시에 사용되는 우선순위이다.
TThreadPriority형은 아래에 정의된 표에 따라 TThread 콤포넌트의 Priority property 값을 정의한다. Windows 우선순위 스케일에 기준으로 각 쓰레드의 CPU cycle을 스케쥴한다.

값                       내용

tpIdle                  시스템이 idle 상태일때만 실행된다. tpIdle의 우선순위를 가진  쓰레드의 실행때문에 다른 쓰레드 프로세스를 interrupt 하지는 않을 것이다.
tpLowest                  normal보다 2 point 낮은 우선순위를 가진다.
tpLower                  normal보다 1 point 낮은 우선순위를 가진다.
tpNormal                  normal 우선순위이다.
tpHigher                  normal보다 1 point 높은 우선순위를 가진다.
tpHighest                  normal보다 2 point 높은 우선순위를 가진다.
tpTimeCritical         최고 높은 우선순위를 가진다.

주 의 : CPU 점유율이 높은 operation의 우선순위를 높이는 것은 동일 Application내에 타 쓰레드 가 동작하지 못하게 할 수도 있다. External event를 기다리는데 대부분의 시간을 사용하는 쓰레드의 우선순위를 높여라.


@ WaitFor

쓰레드를 종료되기를 기다리고,  종료시 ReturnValue property를 return한다.

(원형) int __fastcall WaitFor(void);

(상 세)  WaitFor를 호출하면 쓰레드 종료 시 ReturnValue를 얻을 수 있다. WaitFor는  Execute 메쏘드가 끝나거나 Terminated property = true 가 되어 빠져나와서 쓰레드가 종료될때까지 return되지 않는다.

--------------------------------------------------------------------------------------------------

이번에 BDS 2006으로 바뀌면서 몇가지 바뀐것이 있는데요,
그중 하나가 Synchronize의 사용법 입니다. 저는 이걸 몰라서 몇일동안 고생해서
외국의 포럼에서 찾은 내용 팁란에 올립니다.

기존에는
void __fastcall CTEST::Test()

라는 메소드를 동기화 시키려면
Synchronize(Test);
라고만 쓰면 됬는데 새롭게 바뀐 문법에서는

Synchronize(&Test);

이렇게 쓰셔야 에러 안납니다.

------------ 볼랜드포럼에서 발췌 ---------------------------------------

Posted by 가희나희아빠 희자매(가희나희)아빠
TAG 쓰레드
S/W 개발/Embarcadero2007.12.06 10:22
다음과 같은 방법을 사용하면 된다.. 특히 [] 주의... (이거 땜시 고생한거 생각하믄..  ^^;]

combo1->Items->Strings[combo1->ItemIndex]

만약 String 속성이 아닌 Text 속성을 사용하면 전체 리스트가 뿌려짐...

하나씩 뿌리는것은 아예 에러가 발생..

'S/W 개발 > Embarcadero' 카테고리의 다른 글

쓰레드 만들기..  (0) 2007.12.06
ComboBox에서 현재 선택된 값 받기..  (0) 2007.12.06
AnsiString을 char형태로 바꾸기.  (0) 2007.12.06
날짜 형식 변경  (0) 2007.12.06
Posted by 가희나희아빠 희자매(가희나희)아빠
S/W 개발/Embarcadero2007.12.06 10:22
AnsiString으로 정의된 변수 뒤에..
c_str() 를 붙여주면 자동을 변환됨...

'S/W 개발 > Embarcadero' 카테고리의 다른 글

ComboBox에서 현재 선택된 값 받기..  (0) 2007.12.06
AnsiString을 char형태로 바꾸기.  (0) 2007.12.06
날짜 형식 변경  (0) 2007.12.06
char*를 wchar_t*로 형변환...  (0) 2007.12.06
Posted by 가희나희아빠 희자매(가희나희)아빠
TAG 형변환
S/W 개발/Embarcadero2007.12.06 10:16
[이용함수]
    TDateTime의 FormatString()
[함수정보]

    AnsiString FormatString("포멧", 날짜변수);
[사용  예]

    Edit1->Text = Now().FormatString("yyyy-mm-dd hh:nn:ss");
[포멧정보]
   y -> 년, m -> 월, d -> 일
   h -> 시, n -> 분, s -> 초
   특정 문자를 넣을려면 넣을려는 문자(혹은 문자열)을 ' 로 묶으면 됩니다
     예=> Now().FormatString("yyyy'년' dd'월' hh'시' nn'분' ss'초 입니다'");

---------------------------------------------------------------------------------------------------
날짜와 데이터만 얻을 경우에는 다음과 같이 사용해도 무난함..
Date().FormatString("yyyy.mm.dd");
Time().FormatString("hh:mm:ss");

뭐.. 이리 하나.. 저리하나.. 같은 거...

'S/W 개발 > Embarcadero' 카테고리의 다른 글

AnsiString을 char형태로 바꾸기.  (0) 2007.12.06
날짜 형식 변경  (0) 2007.12.06
char*를 wchar_t*로 형변환...  (0) 2007.12.06
BDS2006(C++ 빌더)에서 외부 ActiveX 사용하기  (0) 2007.12.06
Posted by 가희나희아빠 희자매(가희나희)아빠
TAG 날짜
S/W 개발/Embarcadero2007.12.06 10:14
1) WideString
캐스팅 시키는 함수. 아래 방법으로 하시면, A에 wchat_t 형식으로 Hello가 들어갑니다.

A = WideString("Hello");

2) StringToOleStr
원라는 AnsiString용 함수입니다. char 배열도 사용할 수 있습니다.

A = StringToOleStr("Hello");

3) MultiByteToWideChar
이 방법을 쓰시면 UTF8 형식으로도 변경할 수 있습니다. UniCode를 사용하는 경우, 이 API를 꼭 이용하셔야 합니다. UTF8을 원하시면 CP_ACP 부분을 CP_UTF8 로 바꾸어 주시면 됩니다. 이 방법은 조금 복잡합니다. 먼저 문자열 길이가 얼마나 나오는지 얻어낸 다음, 그 길이만큼 변수를 잡고, 변환을 다시 시켜야 합니다.

String            stString = "HELLO";
int               itWideSize = MultiByteToWideChar(CP_UTF8, 0, stString.c_str(), stString.Length() + 1, NULL, 0);
wchar_t           *wcTarget = new wchar_t[itWideSize];

MultiByteToWideChar(CP_ACP, 0, stString.c_str(), stString.Length() + 1, wcTarget, itWideSize);
=========================================================================================================
볼랜드포럼 유영인님 글에서 발췌

2006/07/05 11:46
Posted by 가희나희아빠 희자매(가희나희)아빠
S/W 개발/Embarcadero2007.12.06 10:13
Component->Import Component 실행

Import ActiveX Control 선택하고 진행

기본적으로 BDS의 Imports 인가 거기에 생성 되는데 다른데 생성해도 상관 없음

???_TLB.cpp,??? _OCX.cpp 등 cpp 관련이 2개 생성됨

BDS에서 새로운 package library 프로젝트를 하나를 만듦
만든후 앞에서 생성한 cpp 파일(???_TLB.cpp,??? _OCX.cpp) 추가 - 미리 생성된 CPP는 삭제하지 말것

Package Compile
Link
Install

ActiveX는 자동으로 컴포넌트가 Install 됨..

간혹 프로젝트에서 나타나지 않을 경우 Project - Option(Shift + Ctrl + F11)로 들어가서
Package Option 탭을 보고 체크되지 않았을경우 체크해 주면 나타나게 됨..

2006/07/04 19:25
Posted by 가희나희아빠 희자매(가희나희)아빠
TAG ActiveX
S/W 개발/Embarcadero2007.12.06 10:09
VS(Visual Studio) 에서는 없는 개념(없다는건 아니고 다른이름이죠) 이라 VS진영에서 넘어오신 분들은 처음에 당혹해 하는 부분입니다만..
borland 는 (물론 C++ Builder와 Delphi) 에서는 VCL 이라는 라이브러리를 사용합니다.
VCL 은 VC++ 에서 MFC 정도라고 할까요? 사실 Windows API를 가지고 Windows Application 을 만드는것은 여간 복잡한(나름대로 익숙하면 그렇지만은 않은) 과정이 많아 이를 단순화 시킨게 MFC라면 VCL도 이러한 관점과 같습니다. 사실 VCL 은 Borland 의 오래전의 OWL(정확한지 기억이 가물가물) 에서부터 유래 합니다.
즉 Windows 의 여러가지 콘트를들을 Visual 하게 작업할 수 있도록 만들어서 제공하는 라이브러리가 VCL입니다.
이 러한 VCL의 주축은 Package Library 에서부터 출발 합니다. VC++에서 DLL 을 만들어 사용하듯이 borland에서도 물론 DLL을 사용할 수 있습니다.. 또한 VCL 이라는 package library 를 사용하고 있습니다. 이러한 package 라이브러리를 만들어 주는 프로젝트가 package library 프로젝트 입니다. 이렇게 만든 프로젝트의 결과물이 바로 bpl 파일 입니다. Borland Package Library 의 약자 이죠.
즉 VC++ 에서 DLL project를 하면 결과가 dll 이 나오듯이 borland의 package library project를 컴파일 하면 바로 bpl 이 나옵니다.
우리가 흔히 component 라고 판매하거나 아니면 다른사람이 만든것을 가져다 쓸수 있는 구조가 바로 bpl 입니다.
그러나 bpl 만 있으면 사실 프로그램에 직접 가져다 같이 컴파일 할 수 없습니다.
DLL 파일을 우리가 사용할려면 사실 DLL 에 있는 함수가 어떤것이 있는지를 선언해주는 header가 같이 있어야
우리의 코드에 적용할 수 있는 이치와 같이 bpl 도 header 가 있어야 합니다.
이러한 bpl을 가져다 다른프로그램에 접목시켜 프로그래밍을 하려면 bpi 파일과 header 파일이 있어야 합니다.
또한 bpl 에 만약 폼(Form) 이 같이 포함되어 있으면 해당 dfm (Design Form 의 약자인지 사실 Delphi Form의 약자인지는 혼동) 파일도 같이 있어야 합니다.
우리가 어떠한 판매되는 package library(component 라고 흔히 합니다) 를 구입하면 source code수준까지 구입하지 않을경우 바로 bpl + bpi + dfm 이 같이 들어 있습니다.

그리고 실제 실행파일을 실행하는 환경에서는 bpl 만 있으면 됩니다. (bpi 및 dfm 은 개발자 환경 파일이라 생각하면 됩니다).

Install 이라는것은 package library 즉 bpl 파일을 BDS (BCB6 나 그전도 마찬가지) 에 등록해야 사용할 수 있습니다. 이를 Install Package 라고 합니다. 즉 package library를 BDS에 등록하는 것이죠 프로그램에 쓸수 있도록.

C# 으로 .NET 환경에서 프로그래밍 하신 경험이 있으시면 .NET Assembly 라는 용어를 들어 보셨으리라 생각 합니다. bpl 은 이런 Assembly 와 같은 개념이라 생각하시면 됩니다.

제 생각에는 C# 은 바로 언어구문은 C , C++, Java 구문을 많이 따르고, 소스 파일 구문은 Delphi Pascal 을 많이 따르고(Header 를 사용하지 않고 using 문을 쓰는점에서)  Assembly 개념은 bpl 을 많이 따른 그야말로 장점을 모아 모아 만들긴 한거 같습니다...(그렇다고 만능은 아니고요)

Visual Studio (C#의 경우) 는 ActiveX 나 COM 을 직접 참조하여 프로그래밍 할수 있습니다. .NET 환경에서도 마찬가지고요... 그러나 C++ Builder에서는 이를 직접 사용하지 못합니다.

앞에서 우리가 ActiveX 에서 몇개의 C++ 파일을 BCB 에서 자동으로 만들어 주는 과정을 거쳤습니다.
여기에서 만들어지는것은 몇가지 C++ 와 바로 Type Library 라는 것을 만들어 줍니다. Type Library 라는것은
그전의 object 파일이 어떤 컴파일러든 링크 가능하던 시절이 지나고 서로 호환을 갖지 못하게 되었으며 이로 인해
MS에서는 type library라는 것을 제공하게 됩니다.
type library 는 간단히 말하면 어떤 코드(라이브러리 코드 , 컴파일된 object code 라 생각할 수 있죠) 를 외부에서 사용할때(LINK 할때) 연결하는 규칙이라 생각하시면 됩니다.  OLE 프로그래밍을 해보셨으면 아마 이러한 작업을 했던 경험이 있으실 겁니다.
Property 와 Method 를 만들어 붙이는 것이죠..

즉 BCB 는 ActiveX에서 이러한 소스코드와(실제 소스코드가 아니고 해당 active x에 연결하는 구조) 와 type library 를 만들어 내는 것입니다.

이렇게 만든 코드를 package 라이브러리로 만들어서 바로 bpl을 만들어 주면 BCB 나 BDS2006에서 사용할 수 있는 것 입니다.

처음 접하시는 분들은 좀 어려운 부분이기는 하나.. 매우 중요한 부분으로 Borland 툴의 우수한 기술력이라고 생각 합니다.

OCX를 이용하면 많은 부분을 처리할 수 있습니다. OCX는 기존의 DLL보다는 진일보한 인터페이스를 제공하고 있으니까요..
가령 Acrobat Reader를 자신의 폼에 배치하여 사용할 수도 있습니다.

지금으로서 (.NET을 제외하면) Borland 와 VS 와 연결 창구는 ActiveX 밖에 없는것 같습니다.
==========================================================================================

볼랜드포럼 - 둘리님 글에서 발췌..
==========================================================================================
2006.07.14
Posted by 가희나희아빠 희자매(가희나희)아빠
S/W 개발/Embarcadero2007.12.06 10:07
MFC에서 프로젝트를 FormView를 쓰면 화면 전환시에 사용하는 법은 다음과 같이 난 작성한다...

메인폼에 사용자 메시지를 받을 수 있는 함수를 다음과 같이 작성한다..

이런식의 함수를 사용하고자 하는 곳에서...

::SendMessage(AfxGetMainWnd()->m_hWnd, UM_MENUCHANGE, IDD_LDP_CAL_FORM, NULL);

이런식으로 호출해서 폼이 바뀌는방식을 주로 쓴다..


그리고 C++ 빌더에서는 다음과 같이 사용한다...
1. 이전 화면이 있으면 삭제..
2. 화면 호출 및 생성
3. 화면 크기를 메인폼에 맞게 수정..(Resize 함수 이용)

다음과 같이 처리한다... 어떤 방식이 더 낫다고 볼 수 없다..

어차피, 결과는 똑같으니까..

그런데.. 난 VCL 방식으로 처리하는게 더 좋다.. 왜... 간단하니까....

-2006.06.29 -

 

Posted by 가희나희아빠 희자매(가희나희)아빠
TAG FormView
S/W 개발/Embarcadero2007.12.06 10:04
Posted by 가희나희아빠 희자매(가희나희)아빠

< IplImage >

- OpenCV의 이미지 구조체


// 선언하기 (1차포인터 선언)

 IplImage *pSample = NULL;


// 이미지 로드하기

// cvLoadImage 함수를 이용해서 로드

// 두번째 인자는 양수값이면 강제로 3칼라(RGV), 0이면 강제로 흑백, 음수값이면 이미지 원래의 칼라를 따름

 pSample = cvLoadImage("sample.jpg", 1);
 

// 이미지 세이브하기

// 두번째 인자에 IplImage의 형태는 2차포인터이므로 &pSample 임

int cvSaveImage( char*형 파일이름, &pSample );

 

// 이미지 복사

// 빈 포인터 하나 만들고

IplImage *pCopySample = NULL;

 
//  같은 싸이즈로 빈 이미지를 하나 만들고

pCopySample = cvCreateImage( cvSize(pSample->width, pSample->height) ,IPL_DEPTH_8U, pSample->nChannels );

 

// OPENCV 소스에 있던 내용인데요 origin이 IPL_ORIGIN_TL에 따라 그냥 복사.. 혹은 Flip 시킴

if( image->origin == IPL_ORIGIN_TL )

{
     cvCopy( image, frame_copy, 0 );

}
else
{
     cvFlip( image, frame_copy, 0 );

}

// 복사후 필요없으면 pSample, pCopySample 모두 해지할것...

 

// 닫기

// 릴리즈함수

ReleaseImage( &pSample );

Posted by 가희나희아빠 희자매(가희나희)아빠

티스토리 툴바