Delphi (Pascal) 检查每个字段是否被赋值
Delphi (Pascal) Check if each field is assigned
我正在 Delphi 中使用 windows dll,我必须检查我的功能是否分配得当。
我声明函数类型是为了将我的 dll 函数放在 class 属性中,如下所示:
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 class 中的每个对应字段分配一个方法,如下所示:
@Self.m_MPOS_OpenResource := GetProcAddress( libHandler, '_MPOS_OpenResource@12' );
@Self.m_MPOS_CloseResource := GetProcAddress( libHandler, '_MPOS_CloseResource@8' );
@Self.m_MPOS_GetResourceID := GetProcAddress( libHandler, '_MPOS_GetResourceID@8');
...
最后我检查了每个分配是否都使用了一个巨大的 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;
但是没有用。有人可以帮我吗?
您可以编写一个包装函数来执行测试:
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, '_MPOS_OpenResource@12', @@Self.m_MPOS_OpenResource);
CheckedGetProcAddress(libHandler, '_MPOS_CloseResource@8', @Self.m_MPOS_CloseResource);
CheckedGetProcAddress(libHandler, '_MPOS_GetResourceID@8', @Self.m_MPOS_GetResourceID);
FWIW,处理程序是错误的术语。这是一个模块句柄,因此您的变量应命名为 libHandle
.
我正在 Delphi 中使用 windows dll,我必须检查我的功能是否分配得当。
我声明函数类型是为了将我的 dll 函数放在 class 属性中,如下所示:
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 class 中的每个对应字段分配一个方法,如下所示:
@Self.m_MPOS_OpenResource := GetProcAddress( libHandler, '_MPOS_OpenResource@12' );
@Self.m_MPOS_CloseResource := GetProcAddress( libHandler, '_MPOS_CloseResource@8' );
@Self.m_MPOS_GetResourceID := GetProcAddress( libHandler, '_MPOS_GetResourceID@8');
...
最后我检查了每个分配是否都使用了一个巨大的 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;
但是没有用。有人可以帮我吗?
您可以编写一个包装函数来执行测试:
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, '_MPOS_OpenResource@12', @@Self.m_MPOS_OpenResource);
CheckedGetProcAddress(libHandler, '_MPOS_CloseResource@8', @Self.m_MPOS_CloseResource);
CheckedGetProcAddress(libHandler, '_MPOS_GetResourceID@8', @Self.m_MPOS_GetResourceID);
FWIW,处理程序是错误的术语。这是一个模块句柄,因此您的变量应命名为 libHandle
.