Сосбвенно вызвать получается, но pHost всегда = nil.
Соотвественно на pHost.Start; всё вылетает.
Что я не так делаю?
В проекте использую файл mscoree_TLB.pas полученный через tlbimp
type
TCorBindToRuntimeEx = function(pwszVersion: PWideString; pwszBuildFlavor: PWideString;
startupFlags: DWORD; rclsid: TCLSID; riid: TGUID; var ppv): HRESULT;
...............
procedure TForm1.Button1Click(Sender: TObject);
var
hLib: Cardinal;
CorBindToRuntimeEx: TCorBindToRuntimeEx;
pHost: ICorRuntimeHost;
pAppDomainUnk: IUnknown;
pAppDomain: IUnknown;
hRes: HRESULT;
begin
hLib := LoadLibrary('Mscoree.dll');
@CorBindToRuntimeEx := GetProcAddress(hLib, 'CorBindToRuntimeEx');
if @CorBindToRuntimeEx = nil then
Exit;
hRes := CorBindToRuntimeEx(PWideString(PChar('v1.1.4322')), PWideString(PChar('wks')), 2,
CLASS_CorRuntimeHost, IID_ICorRuntimeHost, pHost);
OleCheck(hRes);
if Succeeded(hRes) then
begin
pHost.Start;
end;
end;
Здравствуйте, <Аноним>, Вы писали:
А>Сосбвенно вызвать получается, но pHost всегда = nil.
А>Соотвественно на pHost.Start; всё вылетает.
А>Что я не так делаю?
А>В проекте использую файл mscoree_TLB.pas полученный через tlbimp
А>А>type
А> TCorBindToRuntimeEx = function(pwszVersion: PWideString; pwszBuildFlavor: PWideString;
А> startupFlags: DWORD; rclsid: TCLSID; riid: TGUID; var ppv): HRESULT;
А>

Стандартная ошибка -- забыл
stdcall.
Вот прототип, который юзаю я:
CorBindToRuntimeEx : function (
pwszVersion : PWideChar;
pwszBuildFlavor: PWideChar;
flags: Cardinal;
const rclsid: TGuid;
const riid: TGuid;
out ppv) : HRESULT; stdcall;
... << RSDN@Home 1.1.4 beta 4 rev. 303>>
Здравствуйте, Spaider, Вы писали:
S>
Стандартная ошибка -- забыл stdcall.
Спасибо! А не мог бы ты привести кусок кода вызвающий эту функцую, у меня почему то вылетал exception.
Кода сейчас под рукой нет (дома) потому привести не могу. Может опять что не так написал..
Здравствуйте, <Аноним>, Вы писали:
А>Здравствуйте, 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>>
Здравствуйте, Spaider, Вы писали:
S>Обрати внимание, что привязка к mscoree.dll динамическая, и перед началом работы нужно вызвать IniMsCorEeLibrary().
S>Удачи! При ближайшем рассмотрении, создание хоста оказалось не таким уж сложным делом.
S>Файл MsCorEeImports.pas
Спасибо огромное!
Даже больше чем ожидал