Q&A

  • 쓰레드를 DLL파일에 넣었거든요...그런데 메모리 에러가 나네요.
일단 소스를 적어 보겠습니다.

type
  TRecordMember = record
    s_id    : Array of string;
    s_name  : Array of string;
    s_flag  : Array of string;
    CurrCnt : integer; //Current Number
    bConn   : Boolean; //Ado Connection is True or False
  end;
  SrchMemPtr = ^TRecordMember;

  TThreadRun = class(TThread)
    Cur_Val  : Integer;
    sstr     : string;  

    {Component of Forms Receive Variable}
    FGrid1,
    FGrid2,
    FGrid3   : TStringGrid;
    FSearchConn,
    FPwrConn : TADOConnection;
    FQryMain,
    FQrySub,
    FQryData,
    FQryMethod,
    FQryIns  : TADOQuery;
    FLblTitle: TLabel;
    FEditId  : TEdit;
    FMLog    : TMemo;

    private
      {member variable}
      procedure AutoSearch();
      procedure uf_TagConvert;
      function  ReturnToString(StrHtml: string; sl : TStringList):TStringList;
      function  PostSourceToList(id : string; sl : TStringList):TStringList;
    public
      constructor Create(Grid1, Grid2, Grid3 : TStringGrid;
                         SearchConn, PwrConn : TADOConnection;
                         QryMain, QrySub, QryData, QryIns, QryMethod : TADOQuery;
                         LblTitle: TLabel; edtId : TEdit; mLog : TMemo);export;
      procedure uf_ArrayInitString(ArrayString : array of string);
      procedure uf_ArrayInitInteger(ArrayInteger : array of Integer);
    protected
      procedure Execute;Override;
  end;

  function ExecThread(Grid1, Grid2, Grid3 : TStringGrid;
                      SearchConn, PwrConn : TADOConnection;
                      QryMain, QrySub, QryData, QryIns, QryMethod : TADOQuery;
                      LblTitle: TLabel; edtId : TEdit; mLog : TMemo):Boolean;stdcall;
  //윗부분이 프로그램 부분에서 call할 펑션이거든요...

호출하고, Create하고, Execute로 넘어가다가 엑세스 바이올레이션 에러가 발생을 해요...

var threa: TThreadRun;
      rdMember: SrchMemPtr;


// 구현 부분입니다.
constructor TPowerSearch.Create(Grid1, Grid2, Grid3: TStringGrid;
  SearchConn, PwrConn: TADOConnection; QryMain, QrySub, QryData,
  QryIns, QryMethod: TADOQuery; LblTitle: TLabel; edtId: TEdit; mLog: TMemo);export;
begin
  //form NonView Component
  FSearchConn := SearchConn;  FPwrConn   := PwrConn;
  FQryMain    := QryMain;     FQrySub    := QrySub;
  FQryData    := QryData;     FQryIns    := QryIns;
  FQryMethod  := QryMethod;

  //form ViewComponent
  FMLog      := mLog;         FLblTitle  := LblTitle;
  FEditId    := edtId;        FGrid1     := Grid1;
  FGrid2     := Grid2;        FGrid3     := Grid3;

  FLblTitle.Caption := '정말 어렵네...^^';
  FreeOnTerminate := false;
  inherited Create(false);
end;

{제 생각에는 이부분에서 에러가 나는것 같은데
Dll에서 쓰레드를 이런식으로 클래스 만들어서 쓰는것 자체가 안되는건지...
아니면 포인터를 잘 못써서 그런건지 모르겠군요... }
procedure TPowerSearch.Execute;
begin
//    inherited;
    New(rdMember); //포인터를 초기화
    with FQryMain do begin
        Connection := FSearchConn;
        Close;
        SQL.Clear;
        SQL.Add('select * from ps_main   ');
        Open;
        First;
        rdMember^.Tot_Cnt := RecordCount;

        SetLength(rdMember^.s_id,  RecordCount);
        SetLength(rdMember^.s_name,RecordCount);
        SetLength(rdMember^.s_flag,RecordCount);

        Cur_Val := 0;
        while not Eof do begin
            rdMember^.s_id[Cur_Val]   := FieldByName('id'       ).AsString;
            rdMember^.s_name[Cur_Val] := FieldByName('s_name'   ).AsString;
            rdMember^.s_flag[Cur_Val] := FieldByName('site_flag').AsString;
            FLblTitle.Caption := ' '+rdMember^.s_id[Cur_Val]+
                                 ' '+rdMember^.s_name[Cur_Val];
            AutoSearch;
            Cur_Val := Cur_Val + 1;
            Next;
        end;
        Close;
    end;
    exit;
end;


이정도 소스 입니다.
메모리 에러가 난것을 끄면 다시 정상적으로 사용이 가능합니다.
물론 정상적이다라는 말은 맞지가 않지만, 그래도 제가 원하는 대로 돌아가기는 하더라구요...

근본적인 원인을 알고 싶습니다...

어디가 오류가 난것일까요...?
1  COMMENTS
  • Profile
    최용일 2003.06.20 01:47
    안녕하세요. 최용일입니다.

    DLL에 넣어서 에러가 난 것은 아닌거 같습니다.

    쓰레드의 Execute메소드에서 Main VCL Thread를 직접 건드리는데... 이럴 경우는 Synchronize를 써서 제어해야 됩니다... 쓰레드의 Create에서 파라매터로 넘어오는 객체들이 모두 Main VCL Thread에서 돌아가는 것들인것 같군요...

    ^^ 항상 즐코하세요...