Получить значение свойства типа struct

#.net #reflection #com-interop

#.net #отражение #com-взаимодействие

Вопрос:

Следующий минималистичный пример отлично работает на IronPython (NodaTime свободно доступен по адресу http://nodatime.org /):

 import clr
clr.AddReference('NodaTime')
from NodaTime import SystemClock
print SystemClock.Instance.ToString()
print SystemClock.Instance.Now
  

Он выводит, как и ожидалось:

 NodaTime.SystemClock
2016-10-07T13:25:17Z
  

Однако следующий код Delphi с использованием mscorlib_tlb (уровень взаимодействия .NET) завершается с ошибкой:

 const
  CLASS_CLRMetaHost: TGUID = '{9280188D-0E8E-4867-B30C-7FA83884E8DE}';
procedure CLRCreateInstance(const rclsid: TCLSID; const riid: TIID;
  out pv); safecall; external 'mscoree';

var
  CLR: ICLRMetaHost;
  Runtime: ICLRRuntimeInfo;
  Host: ICLRRuntimeHost;
  CorHost: ICorRuntimeHost;
  Domain: AppDomain;
  Assmbly: Assembly;
  Typ: Type_;
  SystemClock: OleVariant;
  V: IUnknown;

begin
  CLRCreateInstance(CLASS_CLRMetaHost, IID_ICLRMetaHost, CLR);
  Runtime := ICLRRuntimeInfo(CLR.GetRuntime('v2.0.50727', IID_ICLRRuntimeInfo));
  Host := ICLRRuntimeHost(Runtime.GetInterface(CLASS_CLRRuntimeHost, IID_ICLRRuntimeHost));
  Host.Start;
  CorHost := ICorRuntimeHost(Runtime.GetInterface(CLASS_CorRuntimeHost, IID_ICorRuntimeHost));
  CorHost.CreateDomain('', nil, V);
  Domain := V as AppDomain;

  Assmbly := Domain.Load_2('NodaTime');
  Typ := Assmbly.GetType_2('NodaTime.SystemClock');
  SystemClock := Typ.GetField_2('Instance').GetValue(Null);
  WriteLn(Typ.GetMethod_6('ToString').Invoke_3(SystemClock, nil));
  Typ.GetProperty_7('Now').GetValue(SystemClock, nil);
end.
  

Он выводит:

 NodaTime.SystemClock
Exception EOleException in module test.EXE at 000DD9A2.
Значение не попадает в ожидаемый диапазон.
  

(Код исключения на самом деле 0x80070057 E_INVALIDARG «Один или несколько аргументов недопустимы». Странно — я не передаю никаких аргументов.)

Проблема связана со свойством NodaTime.SystemClock.Теперь это возвращает структуру (тип значения) NodaTime.Мгновенно. Похоже, что NodaTime.Instant имеет IsLayoutSequential = True, поэтому структура должна быть совместимой с неуправляемой.

Каков правильный способ получения NodaTime.SystemClock.Теперь из неуправляемого кода?

Комментарии:

1. Хммм, кажется, я сталкиваюсь support.microsoft.com/en-us/kb/309329 Так ли это на самом деле?