Why C++/WinRT requires IDL files for XAML? - c#

For C#,, XAML transpiles to .cs (*.g.cs) files and need no IDL files.
Similarly in C++, Why can't XAML be transpiled to .cpp (*.g.cpp) files and Need any IDL files at all ?
I don't understand.

There's a fair bit of confusion in the question as to how the individual pieces fit together. The main driver for the translation is the IDL file. Irrespective of whether it is authored by a developer or synthesized by the IDE, it is the IDL that produces WINMD (Windows Metadata) files describing the interfaces and runtime classes in a language-agnostic fashion.
The WINMD's are used by all tooling that needs to look up types, query for members (such as properties, events, delegates), and produce application packages.
XAML, on the other hand, isn't part of the compilation process at all. While some of its contents are verified at compile time, it usually gets translated into a compact binary representation (XBF) that's loaded and parsed at runtime to instantiate types.
The question as to why IDL's are required with C++/WinRT (and not with C# or C++/CX) is easily answered: It's simply not possible to derive enough information from C++ class definitions to unambiguously deduce the required metadata.
As an easy example, consider properties. While both C# as well as C++/CX have dedicated language constructs to describe properties, this is not the case in C++. C++/WinRT projects properties to member functions that take zero or one argument (for getters and setters, respectively). If you were to automatically deduce metadata from a C++ class definition, a tool would have to disambiguate between a property and a method. There are other challenges, too, and while Kenny Kerr has repeatedly voiced the desire to get better IDE support for C++/WinRT, the Visual Studio team doesn't seem to care much (see this comment, for example).
For the foreseeable future you should be prepared to author IDL files if you choose to use C++/WinRT.

Related

How do Generics in C# provide source code protection

I am reading the book "CLR Via C#" and in the Generics chapter is said:
Source code protecton
The developer using a generic algorithm doesn't need to have access to the algorithm's source code. With C++ templates or Java's generics, however, the algorithm's source code must be available to the developer who is using the algorithm.
Can anyone explain what exactly is meant by this?
Well, Generic classes are distributed in compiled form, unlike C++, where templates need to be distributed in full source code. So you do not need to distribute the C# source code of a library that contains generic classes.
This does not prevent the Receiver of your class from disassembling it though (as it is compiled to IL which can be rather easily decompiled again). To really protect the code, additional methods, such as obfuscation are required.
Behind the scene: This distribution in compiled form is the reason why C# generics and C++ templates also differ in the way they need to be written. C# generic classes and their methods need to be fully defined at the time of compilation, and any error in the definition of the generic class or their methods or any operation on a template parameter which cannot be deduced at compile time will directly produce a compile error. In C++ the template is only compiled at the time of usage and only the methods actually used are compiled. If you have an undefined operation or even a syntactical error in a template definition, you will only see the error when that function is actually instantiated and used.

How to load an existing assembly with Roslyn, transform it and generate new .cs files

It seems like the documentation around Roslyn is a bit lacking?
I am not able to find good comprehensive documentation.
What I am trying to do essentially is copy the public surface of an existing API (.dll)
into a new assembly (need to create source code .cs files!) and at the same time make a variety of tranformations to the resulting code (think making wrapper classes).
Would really appreciate any help in how I can use Rolsyn to load the initial SyntaxTree from an existing assembly and how to do those basic tranforms (for example exclude internal classes etc)
In the current Roslyn CTP there is a Roslyn.Services.MetadataAsSource namespace which can be used to convert an type's public interface to source code. This is what we implement the F12 "metadata as source" feature with. Now, it generates only a shell of source code which won't actually compile, so you'd have to use further APIs to munge the syntax tree into what you want. Alternatively, you could use the Roslyn.Services.CodeGeneration namespace to generate source from these symbols automatically. I should warn the MetadataAsSource namespace may go away in future versions of the API.
You can import symbols from metadata by creating an otherwise empty compilation with the metadata references you care about added, and then from that compilation browsing the type hierarchy from GlobalNamespace property, or calling Compilation.GetReferencedAssemblySymbol() and then digging through that. This is actually far better than using reflection, since it'll properly express the symbol model from the "C# perspective" instead of the "CLR perspective" -- reflection won't give you information for uses of dynamic, some default parameter values, etc.
It seems like the documentation around Roslyn is a bit lacking? I am not able to find good comprehensive documentation.
Roslyn is at the Community Technology Preview stage, so it's not surprising that its documentation is lacking. You can find some sources at Roslyn API documentation.
What I am trying to do essentially is copy the public surface of an existing API (.dll) into a new assembly (need to create source code .cs files!) and at the same time make a variety of transformations to the resulting code (think making wrapper classes).
Working with assemblies this way is not something Roslyn can do. But it seems for what you want, reflection for reading the assembly combined with Roslyn for writing the new code would work. But you would need to write all the code to translate from the reflection model to Roslyn's model (e.g. Type → TypeDeclarationSyntax, MethodInfo → MethodDeclarationSyntax, etc.).

WinRT Projected types documentation

There is something called projected types in WinRT. For example, in metadata, the IXamlType.UnderlyingType is defined as:
TypeName UnderlyingType { get; }
However when used in a C# app, it changes as follows:
Type UnderlyingType { get; }
My question is - is there any documentation regarding the rules, API, attributes used for such mappings?
That's correct, the language projection built into the CLR maps WinRT types to CLR types automatically. Documentation is hard to come by, especially right now when this is still beta material. But there's an excellent white paper available that describes some aspects of the CLR projection. The download is (currently) available here (Note: Word .docx file)
When windows metadata is created using the low level authoring tools (MIDL with the /winrt switch and MDMERGE), any places in the assembly that would normally use a typedef, the typedef is replaced with typerefs which point inside the same assembly.
That allows the CLR to rewrite the contents of the winmd file replacing the windows runtime type with a corresponding CLR type. The simplest example of this is the Windows.Foundation.Uri type is replaced with System.Uri to C# applications. The CLR knows internally how to map between W.F.Uri and S.Uri and it automatically does this translation for you.
All of this is handled automagically by the system, there are rules for it, but I don't believe that the process is developer controllable - I believe that the type mappings are burned into the CLR implementation.
This is the link I was talking about which is a video on Channel 9 http://channel9.msdn.com/Events/BUILD/BUILD2011/PLAT-874T Please note that this is a video of the Build conference which is based on the Developer Preview. I can't predict how much of this info has changed with the Consumer Preview.
I agree that there should be documentation about how this is working. Hopefully they will update the documentation on MSDN soon.
They say that the source code is the best documentation. In this case it seems to be the only documentation. Here are my findings from spelunking through the .NET source.
The list of metadata projections is encoded in the .NET source using a macro iterator.
This header is included in various places where it is transformed into data structures for the task at hand. The most accessible place to us that I've found is in the WinMD metadata importer and its adapter.
From the source:
// This metadata importer is exposed publically via CoCreateInstance(CLSID_CorMetaDataDispenser...).
// when the target is a .winmd file. It applies a small number of on-the-fly
// conversions to make the .winmd file look like a regular .NET assembly.
My take is that you can use CoCreateInstance(CLSID_CorMetaDataDispenser...) to create an IMetaDataDispenser, call OpenScope() with IID_IMetaDataImport with a .winmd file to get the metadata importer. It will then do conversions like IMap to IDictionary for you as you peruse the metadata. I speculate, but I'm pretty sure that's what Visual Studio does when generating type definitions from metadata or interface implementations.
You can also include the header with the macro iterator into your own C/C++ project and transform the data therein into whatever form is most useful for you, e.g. generate code from it.

Converting a C++ program into C#

I'm working on a project where I'm converting C++ code to C# manually. I have working knowledge of C# but I've never used C++ before.
What I need to know is how to deal with the header files, since C# does't have anything like that. Say I have buffer.h and buffer.cpp, would I just convert them both and include them in the same buffer.cs file?
Is the C++ header file in any way related to an Ada spec file?
The distinction between includes ".h files" and source ".cpp files" is only one of convention. The convention is that declaration (functions, classes, etc) are in .h files which are #included in implementation (definition), or .cpp files. For most cases you're fine in collapsing X.h and X.cpp to a single X.cs file.
That said, you still need to take a look at what is going on in each file. A basic understanding of C++ would go a long way here, and something I strongly recommend you acquire before you get too far into your translation.
It might help you to think of a C++ header file as containing two major types of things: the class definition, which defines its member data and "interface" (not to be confused with a C# interface type) and "other stuff". The class definition part contains method prototypes and class member variables.
The good news concerning the prototypes is that you simply don't need them in C#. Clients of your class receive prototype information from the implementation itself via the assembly for the namespace. The data members are contained within your C# class implementation, typically as private members which are exposed through C# properties.
The "other stuff" mentioned above can include #defines, which you typically want to turn into const definitions in C#. Other things such as enumerations have equivalents in C# which you of course move into the .cs file for your class.

COM to .NET Interoperability

If you want to use a COM type in your C# code, the process is straight forward, right? You just need to use the type library importer and that's fine, but what if you don't have one and you can't take a look at the IDL file? You just have the COM DLL server.
As an example, try using the IActiveDesktop interface.
What's the approch used to solve this kind of problem?
There are two kinds of COM interfaces. The one you are familiar with are the ones that restrict themselves to a subset of the COM spec known as "OLE Automation". Also known as ActiveX before that term became associated with security disasters.
Automation compatible interfaces are easy to use from just about any language. They typically inherit from IDispatch, allowing them to be used from scripting languages. And limit themselves to using only automation compatible types for their method arguments. The simple stuff, comparable to the .NET value types, BSTR for strings, SAFEARRAY for arrays, VARIANT for untyped arguments, quite similar to .NET's System.Object.
Another feature they support well is type libraries, the equivalent of .NET metadata. Used by a compiler to know how to call the interface methods. The IDE uses a type library to automatically generate the interop library so you can directly create the wrapper class and call the methods from .NET code.
Well, that's the good news. The bad news is that there are lots of COM interfaces around that do not use the Automation restrictions. They typically inherit from IUnknown and use function arguments that don't marshal well. Like structures. One very large and visible component in Windows that is like this is the shell. Windows Explorer.
That's where IActiveDesktop fits in as well, it is a shell interface and inherits from IUnknown. It is declared in the ShlObj.h SDK header file, there is not even a IDL file for it. And consequently no way to get a type library with its definition. It uses incompatible argument types, like LPCWSTR (a raw pointer to a string) instead of BSTR. And structure pointers like LPCCOMPONENT and LPWALLPAPEROPT. The CLR interop support is powerless to marshal that properly.
Using the interface in C# is technically not impossible, but you have to redeclare the interface. Very carefully, getting it wrong is very easy to do. The fact that source code that already does this is very hard to find is a hint how difficult it is. This squarely falls in the 'not impossible, but what sane programmer wants to maintain code like this' category. The shell is the domain of unmanaged C++ code. And a crew of hardy programmers, because debugging shell extensions is quite painful.

Categories

Resources