Difference CLR and CLI and how to call those from

2019-06-14 05:40发布

问题:

Could somebody tell me what the difference between CLR and CLI is in it's basic functionallity but most important would be which one of them is better?


All I got so far is that using the ICLRRuntimeHost Interface does not allow me to return anything else than an int and the only allowed parameter is a LPCWSTR (see ExecuteInDefaultAppDomain)

At this point I am wondering if one could/would allocate memory e.g. for a struct in his C program, give a pointer as a LPCWSTR string to ExecuteInDefaultAppDomain and translates this pointer back into that struct on the other side to work on that struct. I don't get it how one can work with the limitation of this signator for each function: int fncname(string param);


I took a look at this tutorial but I don't get it how calling C++/CLI from a C program works and how I could return complex objects or anything more complex than an int.


And could somebody please show me HOW I can use CLI within C? I can't seem to find some lines of code that would show how that would work.


回答1:

You can pass and return complex data in CLI. CLI is an intermediate layer. when you pass data from a managed code(.NET) to native code (c,c++) you need a intermediate layer which will take responsibility of managed to native object and vice verse conversation because managed objects are managed by Garbage collector and native objects are managed by programmer (need to delete when created).

In C++/CLI there are two type of class. 1) Manged class 2) Native class. A managed class is defined as :

public ref class ManagedClass
{
NativeObject* native;
ManagedObject^ mObject;
}

This can contain managed and native object. So in this class you create a managed/native class object which is replica of native/managed object (in terms of containing data and method). The basic data in any object is either another object or basic primitive data which can be easily converted. You have to take care of objects only.

Suppose you want to execute C++ method form .NET. Your c++ code has an object called NativeClass and your c++ method return this native object. You can't pass this object directly to .NET layer. So you will store that object instance in variable native of above class ManagedClass. Note that you can access native as well as managed object in CLI layer. Now you create a manged object class in CLI which will be exact replica of native class in term of containing data. Now you copy all date from Native object to managed object and assign that managed object instance to variable mObject. Now you can pass this variable mObject to .NET layer because this is Manged object.

Similar approach can be used when you pass Managed object to Native method.

You can go through this PDF to know more about C++/CLI.

http://asawicki.info/Download/Productions/Publications/CPP_CLI_tutorial.pdf


UPDATE:

I will recommend you to first go through the PDF. Below is a simple example how this conversion happens. NativeObject is C++ object (You can also have C struct instaed of Class) and ManagedObject is C# object and CLIInterface is used to provide interface.

public ref class CLIInterface
{
private:
    NativeObject* native;
    ManagedObject^ mObject;
public:
    CLIInterface(NativeObject* nativeObj){
        native = nativeObj;
        mObject = gcnew ManagedObject(nativeObj);
    }
    string getNativeMessage();
    int getNaiveID();
    String^ getManagedMessage();
    int getmanagedID();
}

Native class:(C++ Object or C struct and can be used in CLI)

public class NativeObject
{
private:
    int id;
    string msg;
public:
    string getMessage(){return msg;}
    int getID(){return id;}
}

Managed class: (C# object and you can use it in CLI)

public ref class ManagedObject
{
private:
    NativeObject* native;
public:
    ManagedObject(NativeObject* obj){
        native = obj;
    }
    String^ getMessage(){
        convertNativeToCLI(native->getMessage()); //you can use marshaling to implement convertNativeToCLI method. 
    }
    int getID(){
        return native->getID();
    }
}

You can use Managed class object and CLIInterface from C# code and you can use Native Object in C++ code. I hope this will help. You can also go to Microsoft's C++/CLI documentation.