'RyuLib/RyuLib for Delphi'에 해당되는 글 18건

  1. 2013.07.13 RyuLib for Delphi 설치
  2. 2013.01.21 LZMA for Delphi
  3. 2012.10.21 LazyRelease - 메모리 해제를 뒤로 미루기
  4. 2012.08.02 JsonFormatter unit 추가
  5. 2012.07.01 A Simple thread class that can change stack size for it
  6. 2012.06.28 DynamicQueue unit
  7. 2012.01.18 ThreadPool
  8. 2010.12.13 ObserverList
  • SVN Client를 설치합니다.  (http://tortoisesvn.net/ 추천)
  • 파일을 다운 받습니다.  (Checkout)
    • 다운 받을 폴더를 선택합니다.
    • 해당 폴더에서 cmd 창을 열고 프롬프트 창에서 아래를 입력합니다.
    • svn checkout http://ryulib4delphi.googlecode.com/svn/trunk/ ryulib4delphi  [Enter]
  • "Root\XE2\Ryu Open Tools API" 폴더에 있는 SetReg.exe를 실행합니다.  Path를 레지스트리에 등록하게 됩니다.
  • 아래 두 패 키지를 델파이에서 열고 Install 합니다.
    • "Root\XE2\RyuLib.dpk"
    • "Root\XE2\Ryu Open Tools API\RyuOpenToolsAPI.dpk"


레지스트리 등록 내용

[HKEY_LOCAL_MACHINE\SOFTWARE\RyuLib\Delphi\OpenToolsAPI]

"Path"="C:\\Projects\\Lib\\RyuLib\\Delphi\\XE2\\Ryu Open Tools API\\Template\\"



[그림 1] checkout 실행 모습


Posted by 류종택

7-Zip 9.22 beta 버전의 소스를 빌드하여 LZMA.dll을 만들고, 이에 대한 델파이 유닛을 만들었습니다.  보다 최근 버전들은 알파상태라 일단 패스 ^^*


압축속도는 느리지만, 압축률만큼은 대단하네요!


우선 간단하니까 소스는 아래의 링크에서 참고하실 수 있습니다.

http://code.google.com/p/ryulib4delphi/source/browse/trunk/XE2/LZMA.pas


그리고, DLL은 

http://code.google.com/p/ryulib4delphi/source/browse/trunk/XE2/LZMA.dll


별거 없는데 쓸데 없는 시행착오를 좀 했습니다 ㅠ.ㅠ

props라는 인자가 있는데, 이넘이 아마도 프로퍼티를 의미하는 가 봅니다.  압축할 때 썼던 것을 그대로 압축 해제할 때도 사용해야 합니다.  저는 아무 생각없이 새로 정의해서 사용하다가 계속 에러를 찾느라 고생했었습니다.  제가 발견한 예제와 달리 아예 압축하고 난 데이터 안에 해당 데이터를 함께 집어넣어서 해제할 때 아무 생각없이 사용할 수 있도록 하였습니다.


예제는 아래의 링크에 있습니다.

http://code.google.com/p/ryulib4delphi/source/browse/#svn%2Ftrunk%2FXE2%2FSamples%2FLZMA



Posted by 류종택

예를 들어서 var pData : pointer; 변수에 할당된 메모리를 해제하는데 이것이 멀티 스레드 상황에서 다른 스레드에 의해서 사용 중이라거나, 또는 재사용되면 안되는 경우라고 하겠습니다.  이때 단순히 TLazyRelease.Release(pData)를 하면, 당장 메모리 해제는 일어나지 않지만, 언젠가는 결국 메모리에서 사라집니다.  (실제로는 클래스가 아닌 객체의 메소드를 실행해야 합니다.)


가비지 컬렉션처럼 레퍼런스 카운터 등을 이용하면 그러한 문제들을 쉽게 벗어날 수 있겠지만, TLazyRelease 클래스가 보다 쉽고 직관적이며 성능면에서 이득이 많습니다.  (다소 메모리는 낭비 되겠지만..) 

  • 크기를 지정하지 않으면 1024 개의 원소를 가진 링 버퍼가 생성됩니다.
  • Release(pData )를 실행하면, 링 버퍼에 큐처럼 쌓이게 됩니다.
  • 지정된 크기보다 더 입력되면, 가장 오래 전에 입력된 원소를 삭제하고 메모리도 해제합니다.
  • 삭제된 원소를 아직도 사용하고 있거나 하는 경우에는 당연히 에러가 납니다.  TLazyRelease는 메모리의 사용 시간이 링 버퍼가 소진되는 시간보다 작다고 확신 할 수 있을 때만 사용해야 합니다.  아니면 크기를 키워야 합니다.

Clear() 메소드는 자원을 사용하는 모든 스레드를 멈춘 뒤에 사용하는 것이 좋습니다.  프로그램이 종료 되기 전에 사용 된 메모리를 되돌려 놓기 위한 용도입니다.  실행하지 않아도 알아서 해제는 됩니다.


소스: http://code.google.com/p/ryulib4delphi/source/browse/trunk/XE2/LazyRelease.pas

'RyuLib > RyuLib for Delphi' 카테고리의 다른 글

RyuLib for Delphi 설치  (0) 2013.07.13
LZMA for Delphi  (0) 2013.01.21
LazyRelease - 메모리 해제를 뒤로 미루기  (0) 2012.10.21
JsonFormatter unit 추가  (0) 2012.08.02
A Simple thread class that can change stack size for it  (0) 2012.07.01
DynamicQueue unit  (0) 2012.06.28

Posted by 류종택

Json 문자열을 보기 좋게 포멧을 만들어 주는 유닛 입니다.  개인 프로젝트에 필요해서 방금 만든 것이라 예상치 못한 버그가 있을 수 있습니다.


아래와 같은 문자열이 있다고 가정하면,

{"ijl15dec.dll":{"Size":180224,"CRC32":-1072700899},"ijl15enc.dll":{"Size":352256,"CRC32":1671946248},"libspeex.dll":{"Size":245248,"CRC32":1852076076}}


다음과 같이 변환해 줍니다.

{

    "ijl15dec.dll": {

        "Size": 180224,

        "CRC32": -1072700899

    },

    "ijl15enc.dll": {

        "Size": 352256,

        "CRC32": 1671946248

    },

    "libspeex.dll": {

        "Size": 245248,

        "CRC32": 1852076076

    }

}



에러 검증 기능은 없으며, 단순히 정렬만 도와줍니다.  소스는 아래 링크를 참고하시기 바랍니다.

소스: http://code.google.com/p/ryulib4delphi/source/browse/trunk/XE2/JsonFormatter.pas

'RyuLib > RyuLib for Delphi' 카테고리의 다른 글

LZMA for Delphi  (0) 2013.01.21
LazyRelease - 메모리 해제를 뒤로 미루기  (0) 2012.10.21
JsonFormatter unit 추가  (0) 2012.08.02
A Simple thread class that can change stack size for it  (0) 2012.07.01
DynamicQueue unit  (0) 2012.06.28
ThreadPool  (0) 2012.01.18

Posted by 류종택

스택 사이즈를 조절 할 수 있는 간단한 클래스 입니다 ^^*

  • 아무런 추가 기능 없이 쓰레드를 동작하고 멈추기만 합니다.
  • 쓰레드 멈출 때 Timeout을 지정할 수 있습니다.
  • 스택 사이즈를 조절 할 수 있습니다.  기본은 32 KB로 되어 있습니다.

Source: http://code.google.com/p/ryulib4delphi/source/browse/trunk/XE2/SimpleThread.pas


'RyuLib > RyuLib for Delphi' 카테고리의 다른 글

LazyRelease - 메모리 해제를 뒤로 미루기  (0) 2012.10.21
JsonFormatter unit 추가  (0) 2012.08.02
A Simple thread class that can change stack size for it  (0) 2012.07.01
DynamicQueue unit  (0) 2012.06.28
ThreadPool  (0) 2012.01.18
ObserverList  (0) 2010.12.13

Posted by 류종택

구글 코드가 문을 닫아서 깃허브로 옮겼습니다.

메일 문의가 와서 이제서야 알았네요.


Source: https://github.com/ryujt/ryulib4delphi



링크드 리스트를 이용해서 만든 큐를 제공하는 유닛입니다. 

  • 보다 나은 성능을 위해서 작성되었습니다.
    • 델파이에 기본 내장 된 큐 클래스가 TList를 이용하여 빈번하게 메모리 이동이 일어나는 문제 때문에 작성되었습니다.
  • 큐가 Full 상태에서 Push를 하게되면, 공간을 늘려서 저장하게 됩니다.  즉, Full 상태가 되는 일이 없습니다.
  • 쓰레드 세이프하도록 하기 위해서는 TDynamicQueue.Create(True)로 객체를 생성하시면 됩니다.


'RyuLib > RyuLib for Delphi' 카테고리의 다른 글

LazyRelease - 메모리 해제를 뒤로 미루기  (0) 2012.10.21
JsonFormatter unit 추가  (0) 2012.08.02
A Simple thread class that can change stack size for it  (0) 2012.07.01
DynamicQueue unit  (0) 2012.06.28
ThreadPool  (0) 2012.01.18
ObserverList  (0) 2010.12.13

Posted by 류종택
쓰레드 클래스를 생성하지 않고 함수 호출만으로 쓰레드를 사용하기 위한 유닛입니다.  "RyuLib for Delphi" 소스는 아래의 링크에서 받으시기 바랍니다.

http://ryulib.tistory.com/notice/11 


사용법은 [소스 1]과 같습니다.

[소스 1]
function InternalThreadFunction(lpThreadParameter: Pointer): Integer; stdcall;
begin
  Result := 0;

  // TOO : 
end;

procedure TfmMain.btCalcClick(Sender: TObject);
begin
  QueueWorkItem(InternalThreadFunction, nil);
end;
10: 새로운 함수를 쓰레드 풀에 넣어서 실행 시킬 수 있을 때 함수가 실행됩니다.  쓰레드 생성 등에 대한 오버 헤드가 없습니다.

1-6: 함수의 형태는 1-6: 라인과 같아야 합니다.

1: lpThreadParameter 인자는 쓰레드와 호출 객체가 서로 공유 할 데이터나 객체를 전달 받기 위한 것입니다.  필요없으면 사용하지 않아도 됩니다.

ThreadPool 유닛에는 [소스 2]와 같은 형태의 함수가 제공됩니다.  각각 필요한 작업에 따라 선택하시면 됩니다.

[소스 2]
function QueueWorkItem(Func:TThreadStartRoutine; Context:Pointer):boolean;
function QueueIOWorkItem(Func:TThreadStartRoutine; Context:Pointer):boolean;
function QueueUIWorkItem(Func:TThreadStartRoutine; Context:Pointer):boolean;


[소스 3]은 1부터 n까지 더하는 프로그램을 멀티 쓰레드로 작성해 본 것 입니다.  속도를 줄이기 위해서 중간에 Sleep(1)로 쉬도록 했습니다.  [그림 1]은 실행 결과 화면이며, 1000 --> 100 --> 10 순으로 계산을 했지만, 멀티 쓰레드이다 보니 먼저 계산 된 것부터 표시되고 있습니다.  가장 처음 입력한 수는 좀 큰 수였는데, 한 참 동안 계산이 안끝나서 중간에 캡쳐된 것을 올립니다.

[그림 1] 실행 결과


[소스 3]
unit _fmMain;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.Samples.Spin;

type
  TfmMain = class(TForm)
    btCalc: TButton;
    ListBox1: TListBox;
    SpinEdit1: TSpinEdit;
    procedure btCalcClick(Sender: TObject);
  private
    procedure do_WM_User(var Msg:TMessage); message WM_User;
  public
  end;

var
  fmMain: TfmMain;

implementation

uses
  ThreadPool;

{$R *.dfm}

type
  TContext = class
    n : integer;
    Handle : THandle;
  end;

function InternalThreadFunction(lpThreadParameter: Pointer): Integer; stdcall;
var
  Loop, Sum : integer;
  Context : TContext absolute lpThreadParameter;
begin
  Result := 0;

  Sum := 0;
  for Loop := 1 to Context.n do begin
    Sum := Sum + Loop;
    Sleep(1);
  end;

  PostMessage(Context.Handle, WM_User, Sum, Context.n);
end;

procedure TfmMain.btCalcClick(Sender: TObject);
var
  Context : TContext;
begin
  Context := TContext.Create;
  try
    Context.n := SpinEdit1.Value;
    Context.Handle := Self.Handle;
    QueueWorkItem(InternalThreadFunction, Context);
  finally
    Context.Free;
  end;
end;

procedure TfmMain.do_WM_User(var Msg: TMessage);
begin
  ListBox1.Items.Add(Format('Sum = %d, n = %d', [Msg.WParam, Msg.LParam]));
end;

end.
 

'RyuLib > RyuLib for Delphi' 카테고리의 다른 글

LazyRelease - 메모리 해제를 뒤로 미루기  (0) 2012.10.21
JsonFormatter unit 추가  (0) 2012.08.02
A Simple thread class that can change stack size for it  (0) 2012.07.01
DynamicQueue unit  (0) 2012.06.28
ThreadPool  (0) 2012.01.18
ObserverList  (0) 2010.12.13

Posted by 류종택

소스: http://code.google.com/p/ryulib4delphi/source/browse/trunk/XE2/ObserverList.pas

예제: http://bit.ly/VcPLIE



개요

"Observer Pattern" 과 RTTI 를 응용한 클래스입니다.  

다른 점은, 메시지를 수신 받는 객체에서 메시지 안에 있는 문자열과 같은 이름을 가진 메소드가 자동으로 실행 된다는 것 입니다.



예제

unit Unit1;
interface

uses
  ObserverList, ValueList,
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    btSendMsg: TButton;
    procedure FormCreate(Sender: TObject);
    procedure btSendMsgClick(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    FObserverList : TObserverList;
  public
  published
    procedure rp_TestMsg(AParams:TValueList);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.btSendMsgClick(Sender: TObject);
var
  Params : TValueList;
begin
  Params := TValueList.Create;
  try
    Params.Values['Code'] := 'TestMsg';

    Params.Values['Msg'] := 'Hi!!';
    Params.Integers['Year'] := 2013;

    FObserverList.AsyncBroadcast(Params);
  finally
    Params.Free;
  end;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  FObserverList.Remove(Self);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  FObserverList := TObserverList.Create(Self);
  FObserverList.Add(Self);
end;

procedure TForm1.rp_TestMsg(AParams: TValueList);
begin
  ShowMessage(AParams.Values['Msg']);
  ShowMessage(AParams.Values['Year']);
end;

end.

5: ObserverList 유닛과 ValueList 유닛을 추가해야 합니다.  

53: ObserverList 객체를 생성합니다.

54: Form1 자신을 ObserverList 에 등록합니다.  이제부터 메시지는 자동으로 수신됩니다.

48: 더 이상 메시지 수신이 필요하지 않은 경우에는 Remove 메소드를 통해서 수신 등록을 해제합니다.

29-44: 버턴이 클릭되었을 때, 메시지를 전송하는 코드입니다.  ObserverList 에 등록 된 모든 객체에게 메시지를 전송하게 됩니다.  예제에서는 Form1 하나만이 등록되어 있어, Form1 에게만 메시지가 전송됩니다.

TValueList 는 TStringList 를 상속 받아 만들어진 클래스입니다.

35: "Code" 라는 이름으로 "TestMsg" 를 입력하였습니다.  이것은 메시지의 이름입니다.  메시지를 수신 받은 객체는 이 메시지 이름 앞에 "rp_"를 붙인 메소드를 published 에 선언하여 구현하시면 됩니다.  예제에서는 19: 라인에 메소드가 선언되어 있습니다.

37-38: 라인에서는 메시지에 추가적으로 파라메터를 보태서 전송하기 위해 데이터를 추가하고 있습니다.

40: 라인에서는 해당 메시지 정보가 있는 Params 객체를 모든 메시지 수신 객체에게 전송합니다.  비동기적인 방식으로 전송되기 때문에 바로 전달된다는 보장은 없습니다.  바로 전송하기 위해서는 Broadcast(Params) 메소드를 사용하시면 됩니다.

57-61: 라인에서는 전달 받은 메시지를 수신하여 실행 할 메소드가 구현되어 있습니다.  메시지 이름이 "TestMsg" 이기 때문에 메소드 이름은 "rp_TestMsg" 인것을 유의하시기 바랍니다.  rp_TestMsg 메소드를 실행하는 코드는 아무 곳에도 없지만, 단지 메시지를 전송하는 것만으로 이름이 같은 메소드가 자동으로 실행되는 것 입니다.  

만약 ObserverList 에 등록된 객체가 더 있다면, 해당 객체들도 메시지를 수신하게 됩니다.  해당 객체들에 published 에 rp_TestMsg 메소드가 구현되어 있다면, 그 메소드들도 당연히 실행됩니다.  

객체들은 메소드 구현을 하거나 하지 않는 것으로 해당 메시지를 수신 할 것인지 말 것인지를 결정 할 수가 있습니다.






'RyuLib > RyuLib for Delphi' 카테고리의 다른 글

LazyRelease - 메모리 해제를 뒤로 미루기  (0) 2012.10.21
JsonFormatter unit 추가  (0) 2012.08.02
A Simple thread class that can change stack size for it  (0) 2012.07.01
DynamicQueue unit  (0) 2012.06.28
ThreadPool  (0) 2012.01.18
ObserverList  (0) 2010.12.13

Posted by 류종택


티스토리 툴바