Re[3]: ВЫзов CorBindToRuntimeEx из Delphi
От: Spaider Верблюд  
Дата: 18.02.05 09:50
Оценка: 8 (3)
Здравствуйте, <Аноним>, Вы писали:

А>Здравствуйте, Spaider, Вы писали:



S>> Стандартная ошибка -- забыл stdcall.


А>Спасибо! А не мог бы ты привести кусок кода вызвающий эту функцую, у меня почему то вылетал exception.

А>Кода сейчас под рукой нет (дома) потому привести не могу. Может опять что не так написал..

Обрати внимание, что привязка к mscoree.dll динамическая, и перед началом работы нужно вызвать IniMsCorEeLibrary().
Удачи! При ближайшем рассмотрении, создание хоста оказалось не таким уж сложным делом.

Файл MsCorEeImports.pas

unit MsCorEeImports;

interface

uses Windows;

Const
  MsCorEe = 'mscoree.dll';

  STARTUP_CONCURRENT_GC                         = $0001;
    STARTUP_LOADER_OPTIMIZATION_MASK                = $0006;
    STARTUP_LOADER_OPTIMIZATION_SINGLE_DOMAIN        = $0002;
    STARTUP_LOADER_OPTIMIZATION_MULTI_DOMAIN        = $0004;
    STARTUP_LOADER_OPTIMIZATION_MULTI_DOMAIN_HOST    = $0006;
    STARTUP_LOADER_SAFEMODE                          = $0010;
    STARTUP_LOADER_SETPREFERENCE                    = $0100;


//HRESULT CorBindToRuntimeEx(
//  LPWSTR pwszVersion,
//  LPWSTR pwszBuildFlavor,
//  DWORD flags,
//  REFCLSID rclsid,
//  REFIID riid,
//  LPVOID* ppv
//);

Var
  CorBindToRuntimeEx : function (
                                  pwszVersion : PWideChar;
                                  pwszBuildFlavor: PWideChar;
                                  flags: Cardinal;
                                  const rclsid: TGuid;
                                  const riid: TGuid;
                                  out ppv) : HRESULT; stdcall;

//void STDMETHODCALLTYPE CorExitProcess(int exitCode);
  CorExitProcess : procedure (exitCode: Integer); stdcall;

function IniMsCorEeLibrary : Boolean;
procedure FreeMsCorEeLibrary;

implementation

Uses SyncObjs;

Var
  Lock         : TCriticalSection;
  MsCorEeLib   : THandle;
  RefCount     : Integer;

function IniMsCorEeLibrary : Boolean;
Begin
  Lock.Enter;
  try
    Inc(RefCount);
    If MsCorEeLib=0 Then MsCorEeLib := LoadLibrary(MsCorEe);
    If MsCorEeLib>0 Then
    Begin
      CorBindToRuntimeEx := GetProcAddress(MsCorEeLib, 'CorBindToRuntimeEx');
      CorExitProcess := GetProcAddress(MsCorEeLib, 'CorExitProcess');
    End;
    Result := MsCorEeLib>0;
  finally
   Lock.Leave;
  End;
End;

procedure FreeMsCorEeLibrary;
Begin
  Lock.Enter;
  try
    If RefCount>0 Then Dec(RefCount);

    If (MsCorEeLib<>0) and (RefCount=0) Then
    Begin
      FreeLibrary(MsCorEeLib);
      MsCorEeLib := 0;

      CorBindToRuntimeEx := nil;
      CorExitProcess := nil;
    End;
  finally
    Lock.Leave;
  end;
End;

initialization
  Lock := TCriticalSection.Create;
finalization
  while RefCount>0 do FreeMsCorEeLibrary;
  Lock.Free;
end.


Собственно, создание хоста:

// =============================================================================
procedure RunManagedHost (userName: string; daysLeft: Integer);
Var
  hr             : HRESULT;
  host           : ICorRuntimeHost;
  appDomUnk      : IInterface;
  appDom         : _AppDomain;
  ds             : AppDomainSetup;
  appName        : string;
  appType        : _Type;
  appInst        : OleVariant;
  assm           : Assembly;
  getAppMethod   : MethodInfo;
  initMethod     : MethodInfo;
  initParams     : Variant;
  runMethod      : MethodInfo;
  appFactoryFile : string;
Begin
    hr := CorBindToRuntimeEx(
      'v1.1.4322',
      'wks',
      STARTUP_CONCURRENT_GC or STARTUP_LOADER_OPTIMIZATION_SINGLE_DOMAIN,
      CLASS_CorRuntimeHost,
      IID_ICorRuntimeHost,
      host);
    if Failed(hr) then Exit;

  try
    OutputDebugString ('Bind to runtime succeeded');
    OleCheck(host.Start);

    ds := CoAppDomainSetup.Create;
    appName := ParamStr(0);
    ds.Set_ApplicationBase(ExtractFilePath(appName));
    ds.Set_ConfigurationFile(appName + '.config');

    OleCheck(host.CreateDomainEx('<Domain name>', ds, nil, appDomUnk));
    OutputDebugString ('Domain created');
    appDomUnk.QueryInterface(IID__AppDomain, appDom);
        
        ...    
        // Дальше не интересно -- все, что нужно, это через appDom.Load (..) загрузить managed часть и вызвать её
        ...
    finally
        ...
    end;
end;
... << RSDN@Home 1.1.4 beta 4 rev. 303>>
--
К вашим услугам,
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.