Reputation: 1786
I'm trying to compile a minimal example of .NET C++ code (just calling CLRCreateInstance and starting a CLR runtime host). I'm not using Visual Studio, but mingw. I installed the Windows 10 SDK with .NET goodies, and I have the header and lib files correctly installed in Program Files. However, I cannot get g++ to link my program:
$ g++ -o clr.exe -I"C:\Program Files (x86)\Windows Kits\NETFXSDK\4.8\Include\um" -L"C:\Program Files (x86)\Windows Kits\NETFXSDK\4.8\Lib\um\x64" -lmscoree clr.cpp
C:\Users\XXX\AppData\Local\Temp\cciBbZmZ.o:clr.cpp:(.text+0x3d): undefined reference to `_GUID const& __mingw_uuidof<ICLRMetaHost>()'
C:\Users\XXX\AppData\Local\Temp\cciBbZmZ.o:clr.cpp:(.text+0x4f): undefined reference to `CLRCreateInstance'
C:\Users\XXX\AppData\Local\Temp\cciBbZmZ.o:clr.cpp:(.text+0x78): undefined reference to `_GUID const& __mingw_uuidof<ICLRRuntimeInfo>()'
C:\Users\XXX\AppData\Local\Temp\cciBbZmZ.o:clr.cpp:(.text+0xb3): undefined reference to `_GUID const& __mingw_uuidof<ICLRRuntimeHost>()'
collect2.exe: error: ld returned 1 exit status
the program is:
#include <iostream>
#include <Windows.h>
#include <metahost.h>
#include <mscoree.h>
#pragma comment(lib, "mscoree.lib")
int main()
{
HRESULT hr;
ICLRMetaHost *pMetaHost = NULL;
ICLRRuntimeInfo *pRuntimeInfo = NULL;
ICLRRuntimeHost *pClrRuntimeHost = NULL;
// build runtime
hr = CLRCreateInstance(CLSID_CLRMetaHost, IID_PPV_ARGS(&pMetaHost));
hr = pMetaHost->GetRuntime(L"v4.0.30319", IID_PPV_ARGS(&pRuntimeInfo));
hr = pRuntimeInfo->GetInterface(CLSID_CLRRuntimeHost,
IID_PPV_ARGS(&pClrRuntimeHost));
// start runtime
hr = pClrRuntimeHost->Start();
hr = pClrRuntimeHost->Stop();
}
Upvotes: 1
Views: 1090
Reputation: 1786
I finally made it work with the following two corrections:
I switched from vanilla MinGW to an msys2 packaged one. This solved the undefined reference to CLRCreateInstance, which I don't know why was failing with the vanilla MinGW. This basically consisted in downloading msys2 and running pacman -S mingw-w64-x86_64-gcc
.
Thanks to this question I was able to solve the other three undefined references. I'm still not sure how all these COM things work, so unfortunately I'm not sure if this is the right way to solve the problem, or if I just introduced a fatal error but well... I went into mscoree.h
and metahost.h
in .NET SDK install dir, and looked for the things the linker was complaining about.
For example, in mscoree.h
I found:
EXTERN_GUID(IID_ICLRRuntimeHost, 0x90F1A06C, 0x7712, 0x4762, 0x86, 0xB5, 0x7A, 0x5E, 0xBA, 0x6B, 0xDB, 0x02);
so I went to my clr.cpp file and added:
__CRT_UUID_DECL(ICLRRuntimeHost, 0x90F1A06C, 0x7712, 0x4762, 0x86, 0xB5, 0x7A, 0x5E, 0xBA, 0x6B, 0xDB, 0x02);
which seems to work just fine. Did the same for the other two, and my code got into this, which compiled and run without errors:
#include <Windows.h>
#include <metahost.h>
#include <mscoree.h>
#include <cstdio>
__CRT_UUID_DECL(ICLRMetaHost, 0xD332DB9E, 0xB9B3, 0x4125, 0x82, 0x07, 0xA1, 0x48, 0x84, 0xF5, 0x32, 0x16);
__CRT_UUID_DECL(ICLRRuntimeInfo, 0xBD39D1D2, 0xBA2F, 0x486a, 0x89, 0xB0, 0xB4, 0xB0, 0xCB, 0x46, 0x68, 0x91);
__CRT_UUID_DECL(ICLRRuntimeHost, 0x90F1A06C, 0x7712, 0x4762, 0x86, 0xB5, 0x7A, 0x5E, 0xBA, 0x6B, 0xDB, 0x02);
int main(int argc, char *argv[])
{
HRESULT hr;
ICLRMetaHost *pMetaHost = NULL;
ICLRRuntimeInfo *pRuntimeInfo = NULL;
ICLRRuntimeHost *pClrRuntimeHost = NULL;
// build runtime
if (CLRCreateInstance(CLSID_CLRMetaHost, IID_PPV_ARGS(&pMetaHost)) != S_OK) {
printf("[x] Error: CLRCreateInstance(..)\n");
return 2;
}
if (pMetaHost->GetRuntime(L"v4.0.30319", IID_PPV_ARGS(&pRuntimeInfo)) != S_OK) {
printf("[x] Error: GetRuntime(..)\n");
return 2;
}
if (pRuntimeInfo->GetInterface(CLSID_CLRRuntimeHost, IID_PPV_ARGS(&pClrRuntimeHost)) != S_OK) {
printf("[x] Error: GetInterface(..)\n");
return 2;
}
// start runtime
if (pClrRuntimeHost->Start() != S_OK) {
printf("[x] Error: Start(..)\n");
return 2;
}
// start runtime
if (pClrRuntimeHost->Stop() != S_OK) {
printf("[x] Error: Stop(..)\n");
return 2;
}
printf("success!\n");
return 0;
}
Upvotes: 2