从这个问题继续:在 .NET 对象上设置“可为空”属性 https://stackoverflow.com/questions/61334031/setting-a-nullable-property-on-a-net-object
感谢奥利维尔迄今为止的帮助。我现在将这个导入用于 .NET 类型库:https://github.com/DelphiWorlds/MiscStuff/blob/master/Test/mscorlib_TLB.pas https://github.com/DelphiWorlds/MiscStuff/blob/master/Test/mscorlib_TLB.pas它基于 CLR v4,而不是我使用的过时版本。
..我现在有这个代码:
procedure TDotNetObject.SetEnumProperty(const APropertyName: string; const AValue: OleVariant; const ATypeName: string; const AIndex: Integer = -1);
var
LRes: HRESULT;
LEnumType, LPropertyType: _Type;
LInvokeFlags: TOleEnum;
LArgs: PSafeArray;
LConvertedValue: OleVariant;
LPropertyInfo: _PropertyInfo;
LIndex: PSafeArray;
LName: WideString;
LResHex: string;
begin
LPropertyType := nil;
LRes := FType.GetProperty(APropertyName, BindingFlags_Instance or BindingFlags_Public or BindingFlags_NonPublic, LPropertyInfo);
if Succeeded(LRes) then
begin
if ATypeName.IsEmpty then
LPropertyInfo.GetType(LPropertyType)
else
LPropertyType := MTDataClr.GetType(ATypeName); // This is a workaround since for obtaining the underlying type
end;
if LPropertyType <> nil then
begin
// Convert the value to the correct type
LEnumType := MTDataClr.GetCoreType('System.Enum');
LInvokeFlags := BindingFlags_InvokeMethod or BindingFlags_Public or BindingFlags_Static;
LArgs := VariantToPSafeArray(VarArrayOf([LPropertyType, AValue]));
if Succeeded(LEnumType.InvokeMember_2('ToObject', LInvokeFlags, nil, Null, LArgs, nil, LConvertedValue)) then
begin
// ***** Despite the InvokeMember_2 call having "succeeded", LConvertedValue is exactly the same as AValue ****
if AIndex >= 0 then
LIndex := VariantToPSafeArray(VarArrayOf([AIndex]))
else
LIndex := nil;
LRes := LPropertyInfo.SetValue(FTarget, LConvertedValue, LIndex);
if not Succeeded(LRes) then
begin
LResHex := IntToHex(LRes);
Sleep(0);
end;
end;
end;
end;
一切正常,直到 SetValue。 LResHex 是“80070057”,显然等于 ERROR_INVALID_PARAMETER。
有什么线索可以说明我哪里出错了吗?
编辑:根据我添加到代码中的注释,尽管 InvokeMember_2 调用具有“成功”,但 LConvertedValue 是exactly与AValue相同。这可以解释为什么其余部分不起作用。关于如何使 ToObject 调用实际返回“对象”的任何线索?