views:

343

answers:

2

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.

+1  A: 
tommieb75
@Tom: Thanks for the suggestion. But my primary goal (constraint) was not to have a dependency on the CLR at all. If I decide to host the CLR, then it is actually less complex just to call the external stub generator and parse the text output on the fly. So I'm not discounting your answer, but I'm looking for a way for the compiler to run without a .NET runtime at all. Also, consider, I want this to still compile on Linux in the end. I'm sure someone will ask "what is the benefit of targeting CLR while not depending on it." I've not made my mind up on that myself, but please humor me.
mrjoltcola
Maybe a C++ library for reading .NET assembly metadata? I recall researching for one a couple of years ago and did not find anything, except perhaps the Mono toolkit.
mrjoltcola
+1  A: 

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.

Hans Passant
Thanks, this is along the lines of what I was looking for (an unmanaged API).
mrjoltcola