.NET 编译器 - 来自非托管 C++ 的 CLR 程序集元数据访问/反射

发布于 2024-08-21 03:35:51 字数 448 浏览 5 评论 0原文

我有一个针对 .NET 运行时 (CLR) 的编译器。当前版本的编译器是用标准 C++(非托管)编写的。编译器目前缺乏对编译时引用程序集的支持,因此我“导入”.NET 库的方式是使用用 .NET 编写的实用程序存根生成器,它反映任何程序集并以我的自定义语言为其发出签名存根。我为我使用的所有 .NET 程序集预先生成存根。在编译时,我的编译器会编译存根文件以填充符号表等,以便它可以解析 .NET API 中的类型和方法。这就是我的“使用”版本。然而,这是暂时的,现在我想向编译器添加实际的“using”或“import”指令。我需要在编译时访问引用的程序集中的元数据/类型信息。

我的问题:我需要有关如何从非托管 C++ 访问 CLR 程序集元数据的建议。或者,我需要将其转换为托管 C++ 应用程序并使用 .NET 反射支持的理由。纯 C++ 的目的是我还可以在 Linux 上为 Mono 进行编译,此外,除了 CLR 之外,我还为另一个运行时提供了部分后端。

I have a compiler that targets the .NET runtime (CLR). The current version of the compiler is written in standard C++ (non-managed). The compiler currently lacks support to reference assemblies at compile time, so the way I "import" .NET libraries is with a utility stub generator that is written in .NET, which reflects any assembly and emits a signature stub for it in my custom language. I pre-generate stubs for all the .NET assemblies I use. At compile time, my compiler compiles the stub files to populate the symbol tables, etc. so that it can resolve types and methods from the .NET API. That is my version of "using". This was temporary, however, and now I want to add an actual "using" or "import" directive to the compiler. I need to access the metadata / type info in referenced assemblies at compile time.

My question: I need suggestions on how to access a CLR assembly metadata from non-managed C++. Or, I need justification to convert it to a managed C++ app and use the .NET reflection support. The purpose for pure C++ is that I can also compile on Linux for Mono, plus I also have partial backends for another runtime besides CLR.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

晚雾 2024-08-28 03:35:51

我认为这是由 CLSID_CorMetaDataDispenser coclass 的 CoCreateObject() 完成的,请求 IID_IMetaDataDispenser 接口。 IMetaDataDispenser::OpenScope() 允许您打开程序集元数据。请求 IID_IMetaDataAssemblyImport,它有一堆迭代元数据的方法。

请留意 .NET 4.0,它即将到来,我很确定元数据格式已经发生了变化。虽然这应该只是生成元数据的问题,但只要您获得 4.0 版本的接口,读取就应该向后兼容。 具有版本特定元数据组件类的 CLSID。

我假设您对讽刺不感兴趣。

I think it is done by CoCreateObject() the CLSID_CorMetaDataDispenser coclass, asking for IID_IMetaDataDispenser interface. IMetaDataDispenser::OpenScope() lets you open the assembly metadata. Ask for IID_IMetaDataAssemblyImport, it has a bunch of methods to iterate the metadata.

Watch out for .NET 4.0, it's around the corner and I'm pretty sure the metadata format has changed. Although that should only be an issue for generating metadata, reading should be backwards compatible as long as you get the 4.0 version of the interfaces. <cor.h> has CLSIDs for the version specific metadata coclasses.

I'll assume that you're not interested in Irony.

深海里的那抹蓝 2024-08-28 03:35:51

这是来自 MSDN 文章“CLR 全面深入:CLR 托管 API” ',2006 年 8 月。

int main(int argc, _TCHAR* argv[])
{
    // Bind to the runtime.
    ICLRRuntimeHost *pClrHost = NULL;
    HRESULT hrCorBind = CorBindToRuntimeEx(
        NULL,   // Load the latest CLR version available
        L"wks", // Workstation GC ("wks" or "svr" overrides)
        0,      // No flags needed
        CLSID_CLRRuntimeHost,
        IID_ICLRRuntimeHost,
        (PVOID*)&pClrHost);
 
    // Construct our host control object.
    DHHostControl *pHostControl = new DHHostControl(pClrHost);
    
    // Notify the CLR that this host implements hosting managers.
    pClrHost->SetHostControl(pHostControl);

    // Now, start the CLR.
    HRESULT hrStart = pClrHost->Start();

    // Load an assembly and execute a method in it.
    HRESULT hrExecute = pClrHost->ExecuteInDefaultAppDomain(
        pwzAssemblyPath, pwzAssemblyName,
        pwzMethodName, pwzMethodArgs,
        &retVal);
}

还有另一个 MSDN '高级避免和检测 .NET 应用程序中死锁的技术”,2006 年 4 月,其中有一个关于“通过托管 API 进行探索”的部分,这对于解释如何使用 C/C++ 代码进行托管的 API 也很有帮助。

This is from the MSDN article 'CLR Inside Out: CLR Hosting APIs', August, 2006.

int main(int argc, _TCHAR* argv[])
{
    // Bind to the runtime.
    ICLRRuntimeHost *pClrHost = NULL;
    HRESULT hrCorBind = CorBindToRuntimeEx(
        NULL,   // Load the latest CLR version available
        L"wks", // Workstation GC ("wks" or "svr" overrides)
        0,      // No flags needed
        CLSID_CLRRuntimeHost,
        IID_ICLRRuntimeHost,
        (PVOID*)&pClrHost);
 
    // Construct our host control object.
    DHHostControl *pHostControl = new DHHostControl(pClrHost);
    
    // Notify the CLR that this host implements hosting managers.
    pClrHost->SetHostControl(pHostControl);

    // Now, start the CLR.
    HRESULT hrStart = pClrHost->Start();

    // Load an assembly and execute a method in it.
    HRESULT hrExecute = pClrHost->ExecuteInDefaultAppDomain(
        pwzAssemblyPath, pwzAssemblyName,
        pwzMethodName, pwzMethodArgs,
        &retVal);
}

There is another MSDN 'Advanced Techniques To Avoid And Detect Deadlocks In .NET Apps', April, 2006, with a section about 'Spelunking Through the Hosting APIs' which would be of help also, in explaining how to use the APIs for hosting from a C/C++ code.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文