使用非托管代码获取托管信息

问题描述:

嗨:)

我正在用C ++为.Net开发一个简单的编译器,但是我的包含系统遇到了问题,因此似乎找不到一种方法来识别我从dll调用的哪种方法(如果它是void,string) ,int ...
因此,我的include系统调用.net dll调用

Hi :)

I''m developing a simple compiler for .Net, in C++, but am having problems with my include system, therefore not seem to find a way to recognize what kind of method I''m calling from dll if it is void , string, int...
so, my include system call the .net dll call

@include System
@include System:Windows:Forms



什么时候会生成代码,需要知道,什么样的方法...
我想知道是否有人知道一种无需使用工具.net
即可获得方法类型的方法.
我想使用它的一种方式:用C#或另一种.net语言创建一个应用程序以生成TXT,此txt包含方法的名称及其正确的类型,在编译时,我携带此txt并被捕获编译时方法的类型

但是,我想知道是否还有另一种方法.

谢谢.
亚历山大

> ----------------------------------------------

关于这个程序,我说的是:




when will generate the code, need to know, what kind of method...
I wonder if anyone knows a way to get the type of methods, without using tools .net

One way I thought of using it: Create an application in C# or another .net language to generate a TXT, and this txt, contain the name of the methods and their proper type, and at compile time, I carry this txt and caught at compile time the type of method

But, I whant to know, if have an another way.

Thanks.
Alexandre

>----------------------------------------------

About this program that I talked is that:


using namespace System;
using namespace System::IO;
using namespace System::Reflection;

ref class Reflector
{
public:
    void LoadAndReflect(String^ assemblyFileName)
    {
        Assembly^ assembly = Assembly::Load(assemblyFileName);
        array<Type^>^ types = assembly->GetTypes();
        StreamWriter^ sw = gcnew StreamWriter("mscorlib.txt");

        for each(Type^ t in types)
        {
            array<MethodInfo^>^ methods = t->GetMethods();

            for each(MethodInfo^ method in methods)
            {
                String^ base = method->ReturnType->ToString();
                array<String^>^ auxBase = base->Split('.');
                if(auxBase->Length > 1)
                    sw->WriteLine(String::Format("{0} <::> {1}", auxBase[1], method->Name));
                else
                    sw->WriteLine(String::Format("{0} <::> {1}", auxBase[0], method->Name));
            }
        }
        sw->Close();
    }
};

int main(array<System::String ^> ^args)
{
    Reflector^ ref = gcnew Reflector();

    Console::WriteLine("Reflection on {0}", "mscorlib.dll");
    ref->LoadAndReflect("mscorlib.dll");
    return 0;
}



而且,在编译时,我打开该txt并得到方法类型
....


> ----------------------------------编辑12:14(BRT)

我现在知道IMetaDataAssemblyImport,但是,我不知道如何获取该类的信息:(



And, in compiler time, I open that txt and I get the method type
....


>---------------------------------- Edit 12:14 ( BRT )

I know ( now ) about the IMetaDataAssemblyImport, but, I don''t know, how to get the informations usint that class :(

不能使用System::Reflection可以通过一个简单的原因来挖掘非托管代码:它没有反射使用的元数据.

如果您了解.NET的工作原理,则可以看到编译器(和IDE)可以查看"引用程序集的所有元数据,并可以确保在编译过程中所有外部"类型及其成员的正确链接.在C ++中,根本没有这样的东西.创建了针对单模块编程的传统语言,并基于过时的坏脏#include(头文件)和目标文件引入了模块化编程.

实际上,许多使用非托管平台的编程系统的元数据都与多年前的.NET元数据类似:Ada,Turbo Pascal,Object Pascal,Delphi,Modula等. .NET的主要区别在于:旧的元数据完全依赖于实现(不同制造商的Ada编程系统具有不兼容的元数据结构和格式),而且重要的是,元数据未包含在可执行模块中, NET程序集一样.这些系统的元数据在.NET中工作得差不多,但是必须像C ++目标文件或库那样单独提供.元数据可以被认为是对象文件系统的扩展,而不是可执行模块.

如果您仔细研究C ++,C ++/CLI混合模式(托管+非托管)开发,甚至在P/Invoke上,都可以轻松地发现元数据信息是通过实际的源代码(混合模式的情况)还是手动"传递的,通过基于已有知识编写方法的方法签名.你为什么这么认为?因为缺少元数据.这就是为什么不能使Reflection能够看到"非托管代码声明的确切原因.

—SA
You cannot use System::Reflection to dig into unmanaged code by one simple reason: it does not have metadata used by Reflection.

If you understand how .NET works, you can see that the compiler (and the IDE) can "see" all the metadata of referenced assemblies and can ensure correct linkage of all the "external" types and their members during compilation. In C++, there is no such things at all. Legacy languages was created oriented to single-module programming, and modular programming was introduced based on archaic bad dirty #include (header files) and object files.

In fact, many programming systems working with unmanaged platforms, had metadata similar to the .NET metadata many years ago: Ada, Turbo Pascal, Object Pascal, Delp Modula, and a lot more. The major difference with .NET is: that old metadata was totally implementation-depended (Ada programming systems by different manufacturers had incompatible metadata structures and formats), and, importantly, metadata was not included in executable modules, as it is done with NET assemblies. The metadata of those systems worked pretty much line in .NET, but it had to be supplied separately, as with C++ object files or libraries; that metadata could be considered as extension of object-file system, not executable modules.

If you look thoroughly at C++, C++/CLI mixed mode (managed + unmanaged) development and even at P/Invoke, you can easily figure out that metadata information is passed either through actual source code (mixed-mode case) or "manually", by writing method signatures of method based on some preexisting knowledge. Why do you think? Because the lack of metadata. And this is the exact reason why it''s not possible to make Reflection capable of "seeing" the declaration of unmanaged code.

—SA