Q&A

  • [질문] dll 동적호출 방법?
HRESULT WINAPI GetVersionInformation(
    P_VERSION_INFO VersionInfo
);

P_VERSION_INFO 형식은 아래와 같습니다.

typedef struct
{
    ULONG MajorVersion;
    ULONG MinorVersion;
    ULONG BuildNumber;
} VERSION_INFO, *P_VERSION_INFO;


이렇게 정의가 되어있는 dll 파일을
델파이에서 GetVersionInformation 함수를 동적으로
호출할 때 파라메터를 어떻게 보내고 받아야 하나요?

참고로 작성된 코드입니다.

procedure TForm1.Button1Click(Sender: TObject);
type
  VERSION_INFO = record
     MajorVersion  : Cardinal;
     MinorVersion  : Cardinal;
     BuildNumber   : Cardinal;
  end;
P_VERSION_INFO = VERSION_INFO;
TFunc = function( P_VERSION_INFO ) : String;

var
H : THandle;
MyFunc : TFunc;
dllFileName : String;
begin
  dllFileName := RadioGroup1.Items.Strings[ RadioGroup1.ItemIndex ];
  H := LoadLibrary( PChar( dllFileName ) );

  if H < 32 then
    begin
      ShowMessage( 'DLL 함수 address 찾기 실패!' );
      Exit;
    end;

  try
    GetMem( P_VERSION_INFO, SizeOf( VERSION_INFO^ ) );
    @MyFunc := GetProcAddress( H, 'GetVersionInformation( VERSION_INFO )' );
    FreeMem( VERSION_INFO );
    if @MyFunc = nil then
      begin
        ShowMessage( 'DLL Address not found!' );
        Exit;
      end
    else
      begin
        Edit1.Text := ( MyFunc( VERSION_INFO ) );
      end;
  finally
    FreeLibrary( H );
  end;
end;
3  COMMENTS
  • Profile
    최용일 2008.10.25 04:13
    동적이든 정적이든 호출할 때 파라매터 주고 받는 방법은 똑같습니다.
    포인터변수인것 같은데... 메모리 할당한 후에 함수호출해보세요...


    var
    VersionInfo: P_VERSION_INFO;
    begin
    GetMem(VersionInfo, SizeOf(VersionInfo^));
    GetVersionInformation(VersionInfo);
    // use VersionInfo variable
    FreeMem(VersionInfo);
    end;
  • Profile
    최용일 2008.10.25 21:58
    질문이 수정됐군요...

    선언에서 P_VERSION_INFO = VERSION_INFO;는 P_VERSION_INFO = ^VERSION_INFO;로 바뀌어야 될것 같구요...

    GetProcAddress는 DLL에 익스포트된 함수를 얻어오는 함수입니다. 함수명만 주시면 됩니다.
    @MyFunc := GetProcAddress( H, 'GetVersionInformation' );

    MyFunc(TFunc)의 프로토타입선언도 잘못됐군요...
    HRESULT WINAPI GetVersionInformation(P_VERSION_INFO VersionInfo);
    ==>
    function GetVersionInformation(VersionInfo: P_VERSION_INFO): HRESULT; stdcall;
    때문에 아래와 같이 하시는것이 맞습니다.
    TFunc = function (VersionInfo: P_VERSION_INFO): HRESULT; stdcall;

    GetMem/FreeMem사용하는 시점도 함수호출시에 하는것이지 GetProcAddress에서하는것이 아닙니다.
    또한 GetMem에서 할당한 변수명과 FreeMem에서 해제할 변수명도 같아야죠...
  • Profile
    coderoad 2008.10.25 22:10
    dll을 처음으로 사용하다 보니 부족한 부분이 많이 있었습니다.
    그러다 보니 코드상 많은 부분이 오류가 있었네요.
    댓글을 참조하여 코드를 수정하겠습니다.
    최용일님 감사합니다.