6.0 이하 버전 --------------------------
컴파일  전
Project->Options... 메뉴를 선택해서

"Linker" tab 에서, "Linking"이라는 항목에서

"Use dynamic RTL"을 disable
"Packages" tab에서 "Build with runtime packages"을 disable


OCX나 Active X 를 사용시, registry setting

bds 2006 -------------------------------

위의 내용과 동일..

UI변경으로..
페이지컨트롤 대신 트리뷰로 변경 되었음..
  Linker 노드와 Packages 노드에서 찾으면 됨..

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

BCB에서 클래스 참조시 주의사항  (0) 2007.12.06
BDS 단독 실행 프로그램 만들기  (0) 2007.12.06
볼랜드 기본 칼라 Define  (0) 2007.12.06
INI 파일  (0) 2007.12.06
// Color Define
//////////////////////////////////
#define NONE                 clNone
#define AQUA                  clAqua
#define BLACK                clBlack
#define BLUE                   clBlue
#define CREAM                clCream
#define DARKGRAY           clDkGray
#define FUCHSIA               clFuchsia
#define GRAY                   clGray
#define GREEN                 clGreen
#define LIME                    clLime
#define LIGHTGRAY          clLightGray
#define MAROON             clMaroon
#define MEDIUMGRAY      clMedGray
#define MINTGREEN        clMoneyGreen
#define NAVYBLUE          clNavy
#define OLIVEGREEN       clOlive
#define PURPLE              clPurple
#define RED                    clRed
#define SILVER                clSilver
#define SKYBLUE             clSkyBlue
#define TEAL                  clTeal
#define WHITE                 clWhite
#define YELLOW              clYellow
#define DEFAULT             clDefault

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

BDS 단독 실행 프로그램 만들기  (0) 2007.12.06
볼랜드 기본 칼라 Define  (0) 2007.12.06
INI 파일  (0) 2007.12.06
컨트롤 동적 생성..  (1) 2007.12.06
ini
볼랜드에서 제공하는 INI 함수를 이용하기 위해...
IniFiles.hpp 파일을 인크루드 시키고..

#include <IniFiles.hpp>

파일 경로 선언..
#define INI_FILE_IO             ".\\..\\Ini\\Io.ini"

INI 파일을 읽어서.. 화면 캡션 변경...
16진수 처리를 위해.. 약간 수정..
파일 캡션 처리....



쓸경우에는
inifile->ReadString(sSection, sKey, "");
부분을
inifile->WriteString(섹션, 키, 수정값);
방식으로 하면 됨...

if else 보다는 case문이 더 빠름... 그냥.. 귀찮아서.. if else 처리

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

볼랜드 기본 칼라 Define  (0) 2007.12.06
INI 파일  (0) 2007.12.06
컨트롤 동적 생성..  (1) 2007.12.06
컨트롤 내부 속성중... 정렬관련.  (0) 2007.12.06
우선 헤더에 선언할 컨트롤 변수 선언...

TmLED  *XLed[16];                     // Input Led
TPanel *XPanel_Name[16];         // Input 이름부

그 다음 생성하고자 하는 부분에 생성..
여기에서는 ... 16개씩 처리하도록 함...


그리고 종료하는 부분에... 메모리에서 삭제...



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

INI 파일  (0) 2007.12.06
컨트롤 동적 생성..  (1) 2007.12.06
컨트롤 내부 속성중... 정렬관련.  (0) 2007.12.06
[펌] c빌더에서 쓰레드 사용하기  (0) 2007.12.06
  1. 메인폼의 이름을 Form1이라고 가정하면...

    for(int loop=0; loop<Form1->ComponentCount; loop++)
    {
    if(!strcmp( (TLabel *)(Form1->Components[loop])->Name.c_str(), BUF) )
    {
    sprintf(BUF1, (TLabel *)(Form1->Components[loop])->Caption.c_str());
    // 등등.. 원하는 작업을 합니다. 아래처럼..
    // (TLabel *)(Form1->Components[loop])->Left = 10;
    // (TLabel *)(Form1->Components[loop])->Visible = true;
    }
    }


    다음으로 제가 추천하는 방법입니다.

    레이블을 150개나 떨어트리고.. 그 이름을 지정하는것... 노가다인거 같은데요
    동적으로 만드는게 좋을듯 합니다.

    TLabel *myLabel[150];

    for ( int loop=0; loop<150; loop++ )
    {
    myLabel[loop] = new TLabel(Form1);
    myLabel[loop]->Parents = Form1;
    myLabel[loop]->Left = loop%5 * 20;
    myLabel[loop]->Top = loop/5;
    myLabel[loop]->Caption = (String) "T" + (int)loop/30+1 + "LB" + (int)loop%30+1;

    // 이렇게 하면 아래 처럼 별도의 이름이 필요 없을듯..
    // 왜냐하면.. 포인터가 저장되어 있으므로..
    // 그렇지 않더라도.. (1)번방법으로 컨트롤 할 수 있슴.
    myLabel[loop]->Name = (String) "T" + (int)loop/30+1 + "LB" + (int)loop%30+1;
    }

    이렇게 생성하시고 사용은

    for ( int loop=0; loop<150; loop++)
    {
    sprintf(BUF1, myLabel[loop]->Caption.c_str());
    // 등등.. 원하는 작업을 합니다. 아래처럼..
    // myLabel[loop]->Left = 10;
    // myLabel[loop]->Visible = true;
    }

    이렇게 합니다.


    --------- 볼포에서 발췌...

THeaderSection::Alignment Property Specifies how text is aligned within the header section.

Class THeaderSection

Syntax

[C++] __property TAlignment Alignment = {read=FAlignment, write=FAlignment};

Description Use Alignment to specify whether the header section text should be left-justified, right-justified, or centered. These are the possible values of Alignment:
ValueMeaning

taLeftJustify

Align text on the left side of the header section.

taCenter

Center text in the header section.

taRightJustify

Align text on the right side of the header section.

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

컨트롤 동적 생성..  (1) 2007.12.06
컨트롤 내부 속성중... 정렬관련.  (0) 2007.12.06
[펌] c빌더에서 쓰레드 사용하기  (0) 2007.12.06
[펌] 함수 포인터의 단점  (0) 2007.12.06
아! 쓰레드!
──────

쓰레드.. 아직 윈32하에서, 그리고 빌더에서(혹은 델파이에서 쓰레드)를 써보지 않으신 분들은
이 쓰레드라는 녀석에 대해 상당한 본능적인 공포를 가지고 계신 분도 있을겁니다. (사실 접니다... --)
도스시절에 멀티쓰레드 어플을 만드는 것은 거의 예술의 경지였죠.
아주 가끔씩 통신망에 올라오는 '멀티쓰레드 XXX' 혹은 '멀티태스킹 XXX'를 볼때마다 (여기서 XXX를
이상하게 해석하지 마세요..) 제 눈은 존경과.. 시기와.. 경외감에 차다 못해 두려움마저... 흑흑~~~

하쥐만~! 지금은 X나 X나(포유류 이름) 맘만 먹으면 아무라도 쓰레드를 만들고 또 재밌게 갖고 놀다가
없애버릴 수 있는 아주 부담없는 개념이 되었죠. 물론 api 수준의 쓰레드 지원도 볼만합니다만... 어지러워요!
무신 함수들이 그렇게 많은지.. 헐~
그러나 vcl 차원에서 지원되는 쓰레드는, 물론 이것도 api를 래핑한 것이지만, 그래도 훨 사용하기가 편하답니다.
얼마나 사용하기 편하냐구요? 아따 성질 급하기는... 지금부터 나갑니다.


쓰레드란?
─────

먼저.. 아직 쓰레드가 뭔지를 모르실 분들을 위해, 쓰레드의 일반적인 개념에 대해 아주 간단히 살펴봅시다.
멀티쓰레드란 말을 못들어봤다고 해도, 아마 멀티태스킹이란 말은 다 아실 겁니다. (컴맹도 알던데요!)

저도 원래 전산이론에 빠삭한 도사는 못되기 때문에 정확한 정의는 내리기 힘들고, 일반적으로 멀티쓰레드란
말은 멀티태스킹이란 말과 같은 의미로 쓰입니다. 다시말하면? 쓰레드란 하나의 작업이라고 해석할 수 있다는 거죠.
멀티태스킹이란 말은 동시에 여러개의 어플리케이션을 실행할 수 있다는 뜻이 아닙니다!
사실 멀티태스킹이란 말은 여러개의 '어플리케이션' 이 아닌 여러개의 '작업'을 할 수 있다는 거죠.
말장난 같죠? 그런데 사실입니다.

윈32 커널 하의 어플리케이션은 모두 하나 이상의 쓰레드로 구성되어 있습니다. '하나 이상'이라고 한
것은, 모든 어플리케이션은 디폴트로 하나의 쓰레드가 실행되는 상태란 말입니다. 다시 해석해보면,
이 말은 디폴트로는 하나의 작업만 하지만, 어플리케이션을 설계하는 단계에서 '약간의' 수고를 더 해주면
하나의 어플리케이션이 동시에 둘 이상의 일을 할 수 있다는 뜻이 되죠.
잘 이해가 안되시면, 쉽게 생각해서 하나의 어플리케이션 안에 또하나의 어플리케이션을 돌릴 수 있다고
생각해도 되겠네요.


단계1 : 쓰레드 클래스의 뼉다구를 만들자
────────────────────

C++빌더와 델파이의 쓰레드는, 물론 api 수준의 쓰레드함수들을 그대로 쓸수도 있지만, 역시 oop 언어답게
TThread 클래스가 미리 준비되어 있죠! 요 귀여운놈을 상속받아서 클래스를 구축하면 됩니다.

하지만 이걸 매번 직접 코드를 만들려면 귀찮으니까... C++빌더/델파이의 IDE에서 기본 뼉다구(skeleton)
코드를 만들어주는 기능이 있습니다.
델파이 혹은 C++빌더의 File 메뉴의 가장 위에 있는 New 항목을 클릭해서 나오는 New Item 다이얼로그에서
첫번째 탭에 있는 아이콘들 중에서(여기 보면 어플리케이션 , 컴퍼넌트, 폼, dll, 유닛 등의 항목이 있죠)
'Thread object'가 있답니다. 당근 이걸 클릭! 그럼 다이얼로그가 뜨면서 델파이 혹은 C++빌더가 물어봅니다.
'만들 쓰레드클래스의 이름은 뭘로 할거유?...'
역시 어제와 마찬가지로... 학습의 효과를 높이기 위해, 이름을 이렇게 붙여봅시다.
ImpThread. 조오쵸?

이렇게 해서 만들어진 코드가 다음과 같습니다. 자세히 보실 필요는 없고..
그냥 TThread를 상속받고 있다는 것, 그리고 멤버함수가 뭐뭐인지 정도만 봐두세요.
다음은 C++빌더에서 생성되는 코드입니다.



델파이에서 생성되는 코드는 다음과 같습니다.


사족 : 얼마나 갈켜줄까
───────────

자아.. 이렇게 해서 길쭈구리한 코드들을 포함한 새 유닛이 자동생성되었습니다.
생성됐으면? 그걸로 끝인가? 써먹어야지! ^^

사실 이 쓰레드라는 개념은 자그마한 팁이 아니라, 꽤나 복잡한 기술이기도 하고, 또 활용도도 말할 수도 없이
많습니다. 글구 이 TThread 클래스의 메소드와 프로퍼티만 해도 한두개가 아니랍니다. 그럴수 밖에 없는 것이,
sdk의 그 많은 쓰레드 관련 api를 대부분 클래스화했으니...

그럼 임프는 오늘 과연 이 쓰레드에 관련한 모든 것을 다 갈쳐줄수 있을까요?
대답은... 택도 엄따~! 입니다. ^^;;;
쓰레드를 제대로 설명하려면 분량도 웬만한 책 한권은 나올정도인데다가, 무엇보다도... 저도 다 모릅니다! (쿵~!)
그래서.. 이러이러한 관계로.. 오늘은 아주~! 간단한, 하지만 작은 예제 하나를 들어보면서 워밍업만 해봅시다.



뭘 해보까
─────

뭘 하느냐... 아 기다려봐요~
이런 경험이 있을겁니다. for문을 돌리면서 메시지를 처리하려면?
for 루프를 돌고 있는 동안에는 어플리케이션 전체가 busy 상태이므로 특별한 처리를 해주지 않으면 어플리케이션에
넘어오는 메시지들은 전혀 처리되지 못한채 메시지큐에 차곡차곡 쌓이죠. 이 상태가 바로 '응답없음' 상태랍니다.
보통은 이걸 간단히 해결하기 위해 for 루프 내에 Application->ProcessMessages()를 삽입하는데..
이 메소드는 잠시 현재 작업을 잠시 중지시켜놓고 메시지큐에 쌓인 메시지들을 처리하는 역할을 하죠.
문제는.. 이 방식이 상당히 느리단 거죠. 거기다 for 루프내의 코드가 상당히 복잡할 경우 몇번씩이나 같은
Application->ProcessMessages()를 삽입해야 하고.. 느리니까 당연히 시간 정확도가 요구되는 작업에는 쓰면
안됩니다. 이럴때 바로 쓰레드를 씁니다. 물론 딴데도 쓰지만, 여기서 쓰레드의 활용도를 간단한 예제로 설명하는데는
아주 딱이겠네요.


단계 2 : 쓰레드 클래스의 생성자 작성
──────────────────

자아.. 그럼 코드를 작성해봅시다. 아까 만든 ImpThread 그대로 있죠?
거기다 장난을 쳐봅시다.

C++빌더에서는, 헤더에 있는 생성자 선언을 조금 수정해줍니다.
__fastcall TImpThread(bool CreateSuspended);
에서,
__fastcall TImpThread(void);
이렇게 바꿉니다.

마찬가지로, 생성자의 바디 부분도 조금 수정하고 코드 한줄을 추가합니다.


생성자에서 베이스 클래스인 TThread 생성자의 인자로 false를 넘겨주도록 수정한 것을 봐두세요.
TThread의 생성자가 갖는 CreateSuspended 인자는 쓰레드 객체만 생성해두고 실제로 쓰레드를 실행하지는 않고
대기할 것인가의 여부를 결정합니다. 따라서 false를 넘겨주면 생성된 직후에 바로 실행이 시작됩니다.

한편, 델파이에서는...
똑같이 쓰레드 오브젝트를 생성해도, C++빌더에서는 생성자 코드까지 만들어주지만 델파이에서는 생성자를
만들어주지 않습니다. 그러니까 델파이를 쓴다면 생성자 선언과 바디를 직접 만들어줘야 하지요.

interface 섹션의 TImpThread 클래스 선언에, public을 추가하고 다음과 같이 생성자를 코딩해줍니다.
constructor Create;

그리고 위에서 선언한 생성자의 바디를 implementation에 추가합니다.
constructor TImpThread.Create;
begin
  inherited Create(false);
  Priority := tpTimeCritical;
end;

베이스 클래스인 TThread의 생성자로 false를 넘겨준 것은 위의 C++의 경우와 같은 이유입니다.
그리고 역시 똑같이 한줄 더 추가했습니다.

뼉다구 코드에다가 딱 한줄 추가한겁니다. 그쵸?
여기서 Priority는 TThread 클래스의 프로퍼티로서.. 현재 쓰레드의 작업 우선순위를 말합니다.
tpTimeCritical은 가장 높은 단계로서, 시간의 오차가 최소화되어야 하거나 윈도우즈가 아무리 바쁜 상황이라도
반드시 수행되어야 할 작업을 할때 이 tpTimeCritical을 지정합니다. 반대로 가장 낮은 순위는 tpIdle이고, 그 위로
tpLowest, tpLower, tpNormal, tpHigher, tpHighest, 그리고 tpTimeCritical까지 지정이 가능합니다.
그럼, 여기서 tpTimeCritical로 지정한 이유는? 대단한 걸 해보려고? 아닙니다.
그냥 기분이 나서 해봤습니다. 따지지 마세요.


단계 3 : 쓰레드 클래스의 Execute 메소드 작성
───────────────────────

그리고.. 이번엔 그다음 뼉다구인 Execute() 메소드의 바디에다 코드를 작성해 봅시다. 바로 이 Execute 메소드가
쓰레드 자체입니다. 별도의 쓰레드로 나누어 작업을 시킬 바로 그 작업을 이 Execute 메소드에게 시켜먹으면 되는
겁니다. (참고로 생성자나 파괴자, 그외 다른 모든 메소드들은 쓰레드로 동작하지 않으며 프로그램의 메인 쓰레드에서
동작합니다)

먼저 TImpThread 클래스의 선언에 private 섹션에 정수형 변수 qq를 하나 추가합니다. C++이라면,
class TImpThread : public TThread
{
private:
    int qq;
    ...
이렇게 될 것이고,  델파이라면,
  TImpThread = class(TThread)
  private
    qq: integer;
    ...
이렇게 되겠죠.

이제 Execute 메소드에 다음과 같이 코드를 추가해봅시다.
C++에서는,


델파이에서는,

여기서...Terminated가 뭘까요?
Terminated는 속성으로서 현재 쓰레드가 작업중인지의 여부를 가리키는 boolean형 속성입니다.
따라서 Terminated = true가 되는 순간이 현재 쓰레드의 작업을 마쳐야 할 시점이라고 생각하면 되겠습니다.

그러니까.. qq의 값을 1씩 증가시키다가 100으로 나눠 떨어지면 폼의 캡션에 그 값을 표시하고 계속 실행하라...
정도 되겠습니다. 그러면 폼1의 캡션이 미친X처럼 파라라라라락~~~ 카운팅되고 있는 숫자로 정신없는 상황이
눈에 선하죠? ^^


단계 4 : Synchronize()
────────────

여기서 쓰레드 프로그래밍에서 반드시 짚고 넘어가야 할 중요한 오류가 하나 있습니다.
바로 폼의 캡션을 수정하는 부분입니다.
TThread 객체의 Execute에서는 VCL의 폼 관련 루틴은 절대로 직접 접근해서는 안되며, 직접 접근할 수 있는
것은 서브 쓰레드가 아닌 프로그램의 디폴트 쓰레드(메인 쓰레드) 뿐입니다.

그러면, 지금 작성하고 있던 예제의 경우 폼에다가 표시하는 것이 목적인데 방법이 없으면 안되겠죠?
이럴 때 쓸 수 있는 것이 TThread 클래스의 Synchronize() 함수입니다. 이 함수는 Execute() 실행중에
반드시 실행해야 하는 루틴을 디폴트 쓰레드로 실행을 위임합니다. 필요한 루틴들을 별도의 함수로 만들어
분리한 후, 그 함수의 포인터를 Synchronize() 함수로 넘기면 된답니다.

다음과 같이 함수를 추가합니다. 클래스 멤버니까 당연히 클래스 선언 내에 함수 선언도 해주어야겠지요.

그리고 Execute() 내에서 폼에 바로 접근하는 부분도 Synchronize()를 호출하도록 고쳐주어야 합니다.


자아.. 한가지만 더 하고 이 쓰레드 유닛은 끝냅시다. 뭐냐구요? 위에서 Form1을 억세스 했잖아요.
그러니 당연히 인클루드 해야죠. 안그럼 컴파일러가 삐지겠죠? #include "Unit1.h"
이제.. 쓰레드 클래스는 다 만들었습니다. 뭐이리 간단하냐구요? 그러니까 빌더가 조은 거지!
그럼.. 이제부터 실제로 이 클래스의 객체를 생성하고 쓰레드를 시작하는 코드를 작성해봅시다.


단계 5 : 완성된 쓰레드의 사용
──────────────

프로젝트의 메인폼인 Form1에 버튼 두개만 따캉~! 따캉~! 하고 놔봅시다.
그리고 각각 캡션은 "시작!", "종료!" 라고 붙입니다. 그런후에..
"시작!"이라고 캡션을 넣은 Button1을 더블클릭해서 OnClick 핸들러를 만들고,
그안에 코드를 작성합시다.


근데 여기서 써먹은 ImpThread라는 TImpThread 객체는 어디에도 아직 만들지 않았죠? 폼과는 달리 쓰레드는
전역적으로 선언되는 포인터를 자동으로 만들어주지 않습니다. 그러니 직접 선언해줍시다. 어디다가?
그것도 일일이 갈켜줘야해요? 뭐, 폼클래스에 집어넣든지 혹은 유닛에 전역적으로 선언하든지 관계없지만,
폼클래스가 지저분한건 딱 질색이니까 폼 유닛의 위 Button1Click() 함수 바로 위에다가 선언해줍시다.
딴데 하고 싶다고요? 누가 말립니까?

TImpThread *ImpThread; // C++
ImpThread: TImpThread; // 델파이

그리고.. 이번엔 Button2("종료!"라고 캡션을 준 버튼)을 더블클릭해서 핸들러를 작성해봅시다.

뭐.. 간단하지요? 별로 설명할게 없어보입니다만.. 굳이 사족을 달자면, Terminate()는 당연히 TThread의
메소드로서, 쓰레드의 실행을 중지시키는 거죠. 그리고 마지막으로 더이상 쓸모가 없어진 쓰레드를 삭제하고요.

마지막 단계 : 실행해보잣!
─────────────

끝입니다. 설명은 장황했지만, 실제로 작성한 코드는 불과 열줄이 채 되지 않죠?
그런데도 실행해보면, 캡션은 열심히 미친 X 처럼 숫자를 카운트하고 있고, 그동안에도 마치 어플리케이션은
아무 일도 안하고 있는 것처럼 메시지를 잘 처리합니다. 대표적으로 캡션바를 드래그해보면, 바쁘게 카운팅을
하는 중인데도 불구하고 드래깅하는 마우스메시지에 제깍제깍 반응합니다. 신기하지요? ^^


결 론
───

오늘의 팁은 여기까지입니다.
요약하자면.. 사실 쓰레드는 아주 복잡한 내부 처리를 거치는 아주 큰 기술입니다. 다루기도 쉽지 않구요.
하지만 vcl에서는 이 쓰레드 개념을 적절히 래핑하여 아주 재미있게 장난감처럼 갖고놀 수 있는 클래스로
만들어놨습니다.

월요일엔 이 쓰레드를 활용하는 다른 예를 들어보겠습니다.
사실 오늘 쓰레드를 설명한 것도, 월요일에 진행할 다음 팁을 쓰는데 쓰레드 개념이 필수적이기 때문입니다.
뭔지 미리 공개하지는 않겠고.. 아주 많은 분들이 애타게 기다리는 팁이란 것만 귀띔해두죠.
벌써 여기저기에서 관련 질문만 여러번 올라왔던 전력이 있는 팁인데, 아직까지 제대로된 답변이 올라온 걸
본적이 없거든요.

// 볼랜드 포럼에서 발췌..
함수 포인터의 단점은 다음과 같습니다.

1) 디버깅이 어렵다.
(콜백함수나 이벤트 핸들링의 경우가 아니고) 함수 포인터를 사용하여 수동으로 호출하는 함수가 몇십개나 된다고 가정해 봅시다.
분 기하기전에 브레이크 포인트를 걸고 어떤 함수로 분기하고자하는지 알고자 할때는 너무 어렵죠. 예를 들어 변수 a라면 값을 바로 알아 낼 수 있지만, 함수 포인터 p라면 그 값이 어떤 함수를 가리키는지 알 수가 없죠. 이럴때는 분기 가능한 모든 함수에 브레이크 포인터를 거는 수밖에 없습니다.

2) 속도가 느리다.
ANSI C 라이브러리에서 함수 포인터를 사용하는 대표적인 함수인 qsort의 경우를 생각해 봅시다. 대소 비교를 위해서 fcmp라는 함수 포인터를 사용하는 데, 이건 qsort 내부에서 대소 비교가 필요할 때마다 매번 호출됩니다.
실제 정렬하는 시간보다 함수 호출을 위한 비용이 훨씬 크게 되어버립니다.

그래서 ANSI C++ STL에서 이런 문제점을 해결하기 위해 만든 것이 함수 포인터를 대신하는 함수 객체(function object)입니다.
함수 객체란 멤버 함수로 함수 하나만 들어 있는 매우 간단한 클래스입니다.
클래스이기 때문에 당연히 인라이닝할 수 있지요.
그래서, STL의 sort가 C의 qsort보다 무려 67000배나 빠릅니다!

콜백함수나 이벤트 핸들링과 같이 반드시 필요한 경우나,
함수 포인터를 써야만 코드가 매우 간결해지는 경우외에는 가능한 한 사용하지 않는 것이 좋습니다.

출처 : 볼랜드포럼
#include<stdio.h>
#include<conio.h>

//------------------------------------------------------------------
int* (*Func1())();
int* (*Func1_1())();
int* (*Func1_2())();
int* (*Func1_3())();
int* Func2();
int* Func2_1();
int* Func2_2();

#define N 8
int *(*(*a[N])())() = {Func1,Func1_1,Func1_2,Func1_3,NULL,};
/*
위는 배열 a를 선언/정의한 것이며 해석해보면 아래와 같습니다.
형을 해석할 때는 가장 안쪽 괄호부터 합니다.
*a[N] : 원소수가 N개인 포인터 배열 a
       , 이 배열의 각원소인 포인터가 무엇을 가리키느냐는 다음 괄호를 해석.
*() : 포인터를 반환(return)하는 함수
      ,위의 배열 각 원소가 바로 이 함수형으로 정의된 함수를 가리킴
      ,그리고 이 함수가 포인터를 반환한다고 했는데 그 포인터가 어떤 것인지는 다음을 해석
int *() : int*를 반환하는 함수
       ,위의 함수가 반환하는 포인터는 이 함수형으로 정의된 함수를 가리킴.

참고로, 이런 복잡한 형은 거의 사용하지 않습니다.
이해가 잘 안되면 그냥 넘어가시기를 권합니다.
프로그램 경력이 늘면 차츰 쉽게 이해가 됩니다.
다만, 아래 1,2는 알고 계시는게 좋습니다.
1. 포인터 배열과 배열을 가리키는 포인터의 구별
int *arr[16]; 포인터 배열 arr(원소수가 16개이고 각 원소는 포인터(int*))
int (*arr)[16]; 배열(원소수가 16개이고 각원소는 int형)을 가리키는 포인터 변수 arr

2. 포인터를 반환하는 함수와 함수를 가리키는 포인터의 구별
int* Func(float); float형 매개변수 하나를 취하고 포인터를(int*)를 반환하는 함수 Func
int (*Func)(float); 함수(float형 매개변수 하나를 취하고 int를 return)를 가리키는 포인터 Func

3. 어떤 함수가 있을 때 이를 가리키는 포인터 선언/정의 방법
int* Func(float); 함수가 있다고 하면
우선 함수이름 부분을 괄호로 묶습니다: int* (Func)(float);
다음으로 함수이름 바로 앞에 *를 붙입니다: int* (*Func)(float);
마지막으로 이름을 중복되지 않은 원하는 것으로 지정합니다: int* (*pFunc)(float);

4. 특정형으로의 형변환 방법
int* (*Func)(float)로 형변환 하려면
우선 변수의 이름을 지웁니다: int* (*)(float)
전체를 괄호로 묶습니다: (int* (*)(float))

5. typedef
int* (*Func)(float);
위와 같은 형을 만들려면 앞에 typedef를 붙인다음: typedef int* (*Func)(float);
형의 이름을 원하는 것으로 정해주면 됩니다:  typedef int* (*FuncPointerType)(float);
*/

//출처 - 볼랜드포럼

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

[펌] 함수 포인터의 단점  (0) 2007.12.06
[펌]함수 포인터 복합선언?  (0) 2007.12.06
pas 화일을 볼랜드 C++에서 쓸때..  (0) 2007.12.06
BDS에서 TRACE 기능 사용하기...  (0) 2007.12.06
pas
pas 화일을 볼랜드 C++에서 쓸때..

DCC32 -JPHNV 바꿀파일.pas

이렇게 하면...

바꿀파일.hpp 바꿀파일obj가 생성된다..

이파일을 C++ 프로젝트에 넣어서 사용하면 된다..

빌더를 실행시킨후 sysstem.obj를 Projecct --> Add to Project... (Shit+11) 메뉴에서 추가!!

그리고, system.pas 의 함수를 사용하는 곳에 system.hpp를 인클루드하여, 컴파일하여 링크하면 실행이 가능!!

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

컴포넌트로 가능한 화일이라면..
보통 아래와 같은 등록부분이 파일에 포함되어 있다...
//_________________________________________________
procedure Register;
begin
  RegisterComponents('Samples', [TFreeButton]);
end;
//_________________________________________________

파일메뉴에서 컴포넌트를 하나 만들고.. 그안에 바꿀 pas 화일을 넣고 인스톨 시키면 자동으로 컴포넌트가 생성된다..
VC에서 BDS로 넘어오면서 처음에 힘들었던 기능이 TRACE 기능의 부재이다..
실행시키면서 그냥.. TRACE만 보면 되기에...

볼랜드에서도 이와 비슷한 기능을 구현할수가 있다...(물론 함수가 있으니까.. 조금 가공하면 된다..)

BDS에서 TRACE 기능을 하는 함수가 바로 OutputDebugString이다..

이 함수는 인자로 char형을 받으므로.. 프로그램에서 받는 부분을 sprintf(stdio.h 참조)나 wsprintf(vcl에 포함)를 이용해서 형변환을 시켜주면 된다...

간단히 예를 보자..

int MenuValPost,  MenuVal;

char buf[1000];
wsprintf (buf, "MenuValPost - %d, MenuVal  - %d", MenuValPost,  MenuVal);
printf("%d", MenuValPost);


이것을 좀더 응용해 보면..

AnsiString TTT;

TTT.sprintf("MenuValPost - %d, MenuVal  - %d", MenuValPost,  MenuVal);
OutputDebugString(TTT.c_str());


이것의 출력은 Debug의 Event Log 창에 나타난다..


MFC의 습관이 무섭다면...
가장 상위에 define 하는것도 하나의 방법일듯...

#define TRACE OutputDebugString

이렇게 하면.. VC에서 쓰는것이랑 비슷하게 쓸수 있을듯..


자세한 함수 설명은 아래쪽에..

OutputDebugString

The OutputDebugString function sends a string to the debugger for display.

void OutputDebugString(   LPCTSTR lpOutputString ); 

Parameters

lpOutputString
[in] Pointer to the null-terminated string to be displayed.

Return Values

This function does not return a value.

Remarks

If the application has no debugger, the system debugger displays the string. If the application has no debugger and the system debugger is not active, OutputDebugString does nothing.

Windows Me/98/95:  OutputDebugStringW is supported by the Microsoft Layer for Unicode. To use this, you must add certain files to your application, as outlined in Microsoft Layer for Unicode on Windows Me/98/95 Systems.

Requirements

Client: Included in Windows XP, Windows 2000 Professional, Windows NT Workstation, Windows Me, Windows 98, and Windows 95.
Server: Included in Windows Server 2003, Windows 2000 Server, and Windows NT Server.
Unicode: Implemented as Unicode and ANSI versions. Note that Unicode support on Windows Me/98/95 requires Microsoft Layer for Unicode.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Kernel32.lib.

See Also

Basic Debugging Overview, Debugging Functions

+ Recent posts

티스토리 툴바