简体   繁体   English

如何使用 mingw 编译和链接最小的 .NET C++ 程序

[英]How to compile and link a minimal .NET C++ program using mingw

I'm trying to compile a minimal example of .NET C++ code (just calling CLRCreateInstance and starting a CLR runtime host).我正在尝试编译 .NET C++ 代码的最小示例(只需调用 CLRCreateInstance 并启动 CLR 运行时主机)。 I'm not using Visual Studio, but mingw.我没有使用 Visual Studio,而是 mingw。 I installed the Windows 10 SDK with .NET goodies, and I have the header and lib files correctly installed in Program Files.我安装了 Windows 10 SDK 和 .NET 好东西,并且我在 Program Files.EDB 和 libE40DB 文件中正确安装了 Z099FB995346F31C749F6 E40DB However, I cannot get g++ to link my program:但是,我无法让 g++ 链接我的程序:

$ 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();
}

I finally made it work with the following two corrections:我终于使它与以下两个更正一起工作:

  1. I switched from vanilla MinGW to an msys2 packaged one.我从 vanilla MinGW 切换到 msys2 封装的。 This solved the undefined reference to CLRCreateInstance, which I don't know why was failing with the vanilla MinGW.这解决了对 CLRCreateInstance 的未定义引用,我不知道为什么香草 MinGW 会失败。 This basically consisted in downloading msys2 and running pacman -S mingw-w64-x86_64-gcc .这基本上包括下载 msys2 和运行pacman -S mingw-w64-x86_64-gcc

  2. 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.我仍然不确定所有这些 COM 的工作原理,所以不幸的是,我不确定这是否是解决问题的正确方法,或者我是否只是引入了一个致命错误,但好吧......我进入了mscoree.hmetahost.h SDK 安装目录中的 metahost.h,并寻找 linker 抱怨的东西。

For example, in mscoree.h I found:例如,在mscoree.h我发现:

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:所以我去了我的 clr.cpp 文件并添加了:

__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;

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM