Reputation: 6353
I wanted to load a C# assembly in a C/C++ project because native loaders seem cool to me but there is a problem with mscorlib.tlh
. First of all, I'm following codeproject example (first snippet). I created an empty C++ project and at first point it didn't seem to find mscorlib.tlb
but then after changing SDK versions/Platform Toolsets, it however found it but there are some errors.
Current settings:
Windows SDK version: 10.0.17763.0
Platform Toolset: Visual Studio 2017 (v141)
Errors:
1>main.cpp
1>c:\users\admin\desktop\netloader\netloader\debug\mscorlib.tlh(12974): error C2143: syntax error: missing ')' before '||'
1>c:\users\admin\desktop\netloader\netloader\debug\mscorlib.tlh(12974): error C2143: syntax error: missing ';' before '||'
1>c:\users\admin\desktop\netloader\netloader\debug\mscorlib.tlh(12974): error C2059: syntax error: '||'
1>c:\users\admin\desktop\netloader\netloader\debug\mscorlib.tlh(12974): error C2059: syntax error: ')'
1>c:\users\admin\desktop\netloader\netloader\debug\mscorlib.tlh(12974): error C2238: unexpected token(s) preceding ';'
1>c:\users\admin\desktop\netloader\netloader\debug\mscorlib.tlh(12977): error C2143: syntax error: missing ')' before '||'
1>c:\users\admin\desktop\netloader\netloader\debug\mscorlib.tlh(12977): error C2143: syntax error: missing ';' before '||'
1>c:\users\admin\desktop\netloader\netloader\debug\mscorlib.tlh(12977): error C2059: syntax error: '||'
1>c:\users\admin\desktop\netloader\netloader\debug\mscorlib.tlh(12977): error C2059: syntax error: ')'
1>c:\users\admin\desktop\netloader\netloader\debug\mscorlib.tlh(12977): error C2238: unexpected token(s) preceding ';'
1>Done building project "NETLoader.vcxproj" -- FAILED.
Screenshot:
I don't know what's wrong with mscorlib in the latest SDK. There are other unanswered related threads as well.
Upvotes: 0
Views: 1579
Reputation: 6353
I fixed the issue. It was because mscorlib.tlh
used or
for a variable name. All I did was I added auto_rename while importing mscorlib.tlb.
#import "mscorlib.tlb" auto_rename
Upvotes: 7
Reputation: 337
Maybe this can help you: https://github.com/voxsoftware/jxshell.dotnet4/blob/master/ClrHost/ClrHost.cpp
The project is designed for be consumed in VFP via DLL, but can give you an idea how load CLR from c++
Look the important parts: ClrLoad:
void WINAPI ClrLoad()
{
if (ClrVersion.Length() >= 2 && ClrVersion[0] == 'v' && ClrVersion[1] == '2') {
ClrLoadLegacyVersion2();
return;
}
// Tutorial on how this works: https://code.msdn.microsoft.com/windowsdesktop/CppHostCLR-e6581ee0
VerifyHresult(CLRCreateInstance(CLSID_CLRMetaHost, IID_PPV_ARGS(&pMetaHost)));
VerifyHresult(pMetaHost->GetRuntime(ClrVersion, IID_PPV_ARGS(&pRuntimeInfo)));
BOOL fLoadable;
VerifyHresult(pRuntimeInfo->IsLoadable(&fLoadable));
if (!fLoadable) throw HresultException("CLR is not loadable.");
VerifyHresult(pRuntimeInfo->GetInterface(CLSID_CorRuntimeHost, IID_PPV_ARGS(&spRuntimeHost)));
VerifyHresult(spRuntimeHost->Start());
CComPtr<IUnknown> spAppDomainThunk;
VerifyHresult(spRuntimeHost->GetDefaultDomain(&spAppDomainThunk));
VerifyHresult(spAppDomainThunk->QueryInterface(IID_PPV_ARGS(&spDefAppDomain)));
And after ClrLoad, load an assembly from disk:
/// *** Creates an instance of a class from an assembly referenced through its disk path
IDispatch* WINAPI ClrCreateInstanceFrom(char *AssemblyFileName, char *className, char *ErrorMessage, DWORD *dwErrorSize)
{
try {
if (!spDefAppDomain)
ClrLoad();
CComPtr<_ObjectHandle> spObjectHandle;
VerifyHresult(spDefAppDomain->CreateInstanceFrom(_bstr_t(AssemblyFileName), _bstr_t(className), &spObjectHandle));
CComVariant VntUnwrapped;
VerifyHresult(spObjectHandle->Unwrap(&VntUnwrapped));
return VntUnwrapped.pdispVal;
} catch (HresultException ex) {
*dwErrorSize = ex.GetMessage(ErrorMessage);
return NULL;
}
}
Upvotes: 1