#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);
*/

//출처 - 볼랜드포럼
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

출처 : http://www.inprise.co.jp/tips/../qanda/cbuilder/c0003071.html

델파이에서 작성한 함수를 C++ Builder에서 사용하려면, .pas 파일로부터 .obj와
.hpp를 생성할 필요가 있다. 생상하는 방법은 아래와 같으며 DCC32.EXE(빌더에
포함되어있다.)를 사용한다.

// unit1.pas 파일이 있는것을 가정하여
DCC32 -JPHNV unit1.pas

에러가 없으면, unit1.dcu, unit1.obj, unit1.hpp가 생성된다.
이들중 unit1.obj와 unit1.hpp를 사용한다.

먼저 unit1.obj를 Projecct : Add to Project... (Shit+11) 메뉴에서 추가한다.

마지막으로 unit1.pas에 포함되는 함수를 사용하는 곳에 unit1.hpp를 인클루드하여,
컴파일하여 링크하면 실행이 가능하다.

출처 - www.borlandforum.com

"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);

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

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

다음과 같은 방법을 사용하면 된다.. 특히 [] 주의... (이거 땜시 고생한거 생각하믄..  ^^;]

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

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

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

'1.소프트웨어 이야기 > 00.VCL(C++ Builder, Delphi)' 카테고리의 다른 글

쓰레드 만들기..  (0) 2007.12.06
AnsiString을 char형태로 바꾸기.  (0) 2007.12.06
날짜 형식 변경  (0) 2007.12.06
AnsiString으로 정의된 변수 뒤에..
c_str() 를 붙여주면 자동을 변환됨...
[이용함수]
    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");

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

+ Recent posts