我正在使用Delphi XE編寫一個基類,這將允許降序類通過應用註釋映射dll方法。但是,我得到一個類型轉換錯誤,這是可以理解的。使用Rtti設置方法字段
本質的基類應該是這樣的:
TWrapperBase = class
public
FLibHandle: THandle;
procedure MapMethods;
end;
procedure TWrapperBase.MapMethods;
var
MyField: TRttiField;
MyAttribute: TCustomAttribute;
pMethod: pointer;
begin
FLibHandle := LoadLibrary(PWideChar(aMCLMCR_dll));
for MyField in TRttiContext.Create.GetType(ClassType).GetFields do
for MyAttribute in MyField.GetAttributes do
if MyAttribute.InheritsFrom(TMyMapperAttribute) then
begin
pMethod := GetProcAddress(FLibHandle, (MyAttribute as TMyMapperAttribute).TargetMethod);
if Assigned(pMethod) then
MyField.SetValue(Self, pMethod); // I get a Typecast error here
end;
和下降類看起來是這樣的:
TDecendant = class(TWrapperBase)
private type
TSomeDLLMethod = procedure(aParam: TSomeType); cdecl;
private
[TMyMapperAttribute('MyDllMethodName')]
FSomeDLLMethod: TSomeDLLMethod;
public
property SomeDLLMethod: TSomeDLLMethod read FSomeDLLMethod;
end;
我可以不同的方式實現這一點,通過硬編碼的連接每個方法在重寫'MapMethods'中。然而,這將要求每個後代都這樣做,我想避免。
我知道在這種情況下使用的TValue
將包含一個指針而不是正確類型(在這種情況下爲procedure(aParam: TSomeType); cdecl;
)。
我的問題:有沒有辦法將'GetProcAdress'的指針作爲正確的類型,或者直接設置字段(例如使用字段地址'PByte(Self)+ MyField.Offset')你可以用來設置記錄屬性的值)?
在舊RTTI,可以這樣做,但只針對發佈的屬性,沒有任何類型檢查:
if IsPublishedProp(Self, 'SomeDLLMethod') then
SetMethodProp(Self, 'SomeDLLMethod', GetProcAddress(FLibHandle, 'MethodName');
請注意[QualityCentral現已關閉](https://community.embarcadero.com/blogs/entry/quality-keeps-moving-forward),因此您無法訪問'qc.embarcader o.com'鏈接了。如果您需要訪問舊的QC數據,請查看[QCScraper](http://www.uweraabe.de/Blog/2017/06/09/how-to-save-qualitycentral/)。 –