2017-03-27 1 views
2

私はDelphiでWindows DLLを使用しています。機能がうまく割り当てられているかどうかを確認する必要があります。Delphi(パスカル)各フィールドが割り当てられているか確認してください

私はこのような属性はクラスで私のDLL関数を置くために、関数の型を宣言した:

@Self.m_MPOS_OpenResource := GetProcAddress(libHandler, '[email protected]'); 
@Self.m_MPOS_CloseResource := GetProcAddress(libHandler, '[email protected]'); 
@Self.m_MPOS_GetResourceID := GetProcAddress(libHandler, '[email protected]'); 
... 

type 
    MPOS_OpenResource = function (ResID: DWORD; CplNum:BYTE; BlockingMode: DWORD):WORD;stdcall; 
    MPOS_CloseResource = function (ResID: DWORD; CplNum:BYTE):WORD;stdcall; 
    MPOS_GetResourceID = function (CplNum : Byte; ResID : PDWord) : word;stdcall; 
    ... 

その後、私はこのように私のdllクラスの各corespondingフィールドにメソッドを割り当てます

そして私は最終的にそれぞれ割り当てが巨大if句で働いていたことを確認してください。

If(not Assigned(@m_MPOS_OpenResource) OR 
    not Assigned(@m_MPOS_CloseResource) OR 
    not Assigned(@m_MPOS_GetResourceID) OR 
...) then { Some code for exception} 

反射を使用して巨大なif句を避けたいですが、動作するものが見つかりませんでした。私は複数のものを試して、最後のものはこれを始める:

for f in rttiType.GetFields() do 
    if(not Assigned(rttiType.GetField(f.Name).GetValue(Self)) 
     OR (Self.FieldAddress(f.Name) = Nil)) then begin 
    ShowMessage('Field not assigned'); 
    end; 
end; 

しかし、それは動作しません。誰かが私を助けることができますか?

+0

代わりに、[ここ](http://stackoverflow.com/a/9263746/576719)で説明されているように、「遅延ロード」を使用することです。 –

+0

ありがとう、これは私が必要と思われる:) – yanneke

+1

'TRttiField.GetValue()'は 'TValue'を返します。 'Assigned()'をそれに使うことはできません。代わりに 'TValue.IsEmpty'を使用してください。また、 'TRttiField.FieldType.TypeKind'または' TValue.Kind'を使用して、ポインタフィールドで操作していることを確認できます。 –

答えて

6

あなたがテストを実行するためにラッパー関数を記述することができます。

procedure CheckedGetProcAddress(libHandle: HMODULE; const name: string; var proc: Pointer); 
begin 
    proc := GetProcAddress(libHandle, PChar(Name)); 
    if not Assigned(Proc) then 
    raise EProcNotFound.Create(...); 
end; 

は次にあなたが書いた:

CheckedGetProcAddress(libHandler, '[email protected]', @@Self.m_MPOS_OpenResource); 
CheckedGetProcAddress(libHandler, '[email protected]', @Self.m_MPOS_CloseResource); 
CheckedGetProcAddress(libHandler, '[email protected]', @Self.m_MPOS_GetResourceID); 

FWIWを、ハンドラが間違った用語です。これはモジュールハンドルなので、変数の名前はlibHandleとする必要があります。

+1

ありがとう、これは良い考えです! – yanneke

関連する問題