Oxed Frederik
Oxed Frederik

Reputation: 1401

How does language interop work in .Net?

In the .Net framework, I am under the impression that you can write a library in one language (say C++), then import that code and use that library cleanly in some other C# project (assuming they both target the same framework version).

However, I don't understand how this works when there could be methods defined in C++ that wouldn't make sense in some other language like C# or VB.net, such as a method parameter that takes a struct that isn't a pointer.

Perhaps my example doesn't hold up due to my limited knowledge of all the CLR languages, but I have to assume there are things that one language can do that another can't -- and I don't get how these discrepancies are dealt with.

Upvotes: 3

Views: 596

Answers (2)

Hans Passant
Hans Passant

Reputation: 942538

There are different kinds of language interop supported by the .NET framework. First is the kind that Abel talks about, a .NET compiler must generate assemblies who's format is described in the CLI Specification. Standardized as Ecma-335 with strict descriptions of the metadata (type descriptions) and code (IL or Intermediate Language). Which makes interop easy to achieve, one language compiler can read the types of another and the .NET runtime makes them work together.

But you are talking about C++, that's not a managed language. That requires interop with native code. That's not technically very difficult, after all the jitter generates native code as well. You just need a way to describe the native code so there's a reasonable chance of success. There are three different ways:

  • You can declare functions written in native code with the [DllImport] attribute. That works for language runtimes that expose a C style calling interface. The Windows API is like that. This does not include C++, at least not when you take advantage of its support for classes.

  • The CLR has good support for COM, the grand father of .NET and an early language interop standard implemented by Microsoft. Particularly the COM Automation subset works well, you can simply add a reference to the type library of a COM component and .NET tooling automatically generates the glue to expose the COM object model implemented by the component as managed types. Office interop works like that, as well as everything you find in the COM tab of the Add Reference dialog. That may work on code written in C++ although COM certainly doesn't require a COM component to be written in C++. VB6 and Delphi are notable languages that support COM well. And the other way around, you can easily expose .NET code as COM to other runtimes. The WinRT api, the one that lets you write Metro apps that run on Windows 8 is COM based at its core, although it is well hidden in the language projections.

  • The ultimate interop tool and the one you need to use to make C++ code usable is the C++/CLI language. It is an extension built into the Microsoft C++ compiler that allows native C++ code to be compiled into IL and stored in an assembly. With the option to declare managed classes in a C++ style syntax, classes that are directly usable by managed code and that can create native C++ class objects and call their methods. Several parts of the .NET framework were built that way, notably mscorlib, System.Data and PresentationManager, chunks of code that have a strong dependency on native code to get their job done. Think of C++/CLI as the ultimate glue language.

Upvotes: 2

Abel
Abel

Reputation: 57217

It is perfectly well possible to create a method, class, struct, type or whatever in one .NET language that cannot be called by another directly. Calling it indirectly (by means of reflection, for instance) is always possible.

I.e., if you look at any compiled C# project, you'll see that the compiled code contains some code with weird names and characters in it, usually for supporting generics. One such name is <Module> (including the brackets), which, even if it were made a public method, can never be called from C# directly.

Language designers that decide to compile for the CLR must support a minimal subset for public types. This is referred to as CLS Compliance and is about a common naming convention, no public pointers or public unsafe members or classes, no names that only differ by case, no public static fields and some more rules. When they obey to this rule it is guaranteed that any other .NET language can call your methods. They know how to do this, because the rules for this are well laid out and documented.

You can even create non-compliant C# code. It will (usually) compile, but it is not guaranteed that all compliant languages can call your method. The same is true for most other languages, including C++.NET. It is a Microsoft Design Guideline to mark your assemblies as CLSCompliant by default (whether it's written in C++, VB, Ruby doesn't matter).

Upvotes: 3

Related Questions