Rajeshwar
Rajeshwar

Reputation: 11681

Using objects in a managed dll from Native C++

I just started writing a managed dll from C#. I am trying this example from msdn. The example demonstrates how we could call simple methods through native C++. I however extended the example and added a simple method called CheckCar. My question is how would i use the CheckCar method in C++

This is the C# code I have

public class car
{
    public string CarMake { get; set; }
    public int CarModel { get; set; }
}

public interface ICalculator
{
    int Add(int Number1, int Number2);
    int Multiply(int a, int b);
    car CheckCar(car c);
};

public class ManagedClass : ICalculator
{
    public int Add(int Number1, int Number2)
    {
        return Number1 + Number2;
    }

    public int Multiply(int a, int b)
    {
        return a * b;
    }
    public car CheckCar(car c)
    {
        if(c.CarMake.Equals("honda"))
        {
            car _c = new car();
            _c.CarMake = "Honda";
            _c.CarModel = 1232121;
            return _c;
        }
        else
        {
            return null;
        }
    }
}

This is the C++ code

    // Initialize COM.
    HRESULT hr = CoInitialize(NULL);

    // Create the interface pointer.
    ICalculatorPtr pICalc(__uuidof(ManagedClass));

    long lResult = 0;

    // Call the Add method.
    pICalc->Add(5, 10, &lResult);
    wprintf(L"The result is %d", lResult);

    // Uninitialize COM.
    CoUninitialize();

This is what my AssemblyInfo looks like

// General Information about an assembly is controlled through the following 
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("sManagedDLL")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("sManagedDLL")]
[assembly: AssemblyCopyright("Copyright ©  2013")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

// Setting ComVisible to false makes the types in this assembly not visible 
// to COM components.  If you need to access a type in this assembly from 
// COM, set the ComVisible attribute to true on that type.
//[assembly: ComVisible(false)]
[assembly: ComVisible(true)] 
[assembly: AssemblyDelaySign(false)] 
[assembly: AssemblyKeyFile("..\\..\\..\\MyKeyFile.SNK")]

// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("41fc209d-a359-45d7-bf05-b1d93690824d")]

// Version information for an assembly consists of the following four values:
//
//      Major Version
//      Minor Version 
//      Build Number
//      Revision
//
// You can specify all the values or you can default the Build and Revision Numbers 
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

My question is how would I call the car CheckCar(car c); method in C++. How could I access the object car and its properties in C++?

Update:

After updating my code I cannot access the IcarPtr in my C++

Here is my updated C# code

namespace sManagedDLL
{
   [ComVisible(true), InterfaceType(ComInterfaceType.InterfaceIsDual), Guid("13FE32AD-4BF8-495f-AB4D-6C61BD463EA4")]
    public interface Icar
    {
        string GetCarMake(); 
        void SetCarMake(string rx);

        int GetCarModel();
        void SetCarModel(int rx);
    }

    [ComVisible(true), ClassInterface(ClassInterfaceType.None), Guid("13FE32AD-4BF8-495f-AB4D-6C61BD463EA5")]
    public class CarImpl : Icar
    {
        private string carmake;
        private int carmodel;

        public string GetCarMake(){return carmake;}
        public void SetCarMake(string rx) { this.carmake = rx;}

        public int GetCarModel() {return carmodel ;}
        public void SetCarModel(int rx){this.carmodel = rx;}
    }

    public interface ICalculator
    {
        int Add(int Number1, int Number2);
        int Multiply(int a, int b);
        Icar CheckCar(CarImpl c);
    }

    public class ManagedClass : ICalculator
    {
        public int Add(int Number1, int Number2)
        {
            return Number1 + Number2;
        }

        public int Multiply(int a, int b)
        {
            return a * b;
        }

        public Icar CheckCar(CarImpl c)
        {
            if (c.GetCarModel().Equals("honda"))
            {
                CarImpl _c = new CarImpl();
                _c.SetCarMake("Honda");
                _c.SetCarModel(1212132);
                return _c;
            }
            else
            {
                return null;
            }
        }//end method
    }
}

Upvotes: 0

Views: 2254

Answers (1)

Zdeslav Vojkovic
Zdeslav Vojkovic

Reputation: 14591

You must expose Car as a COM object (same way as you do for ManagedClass and ICalculator), then instantiate it and send it to CheckCar method.

There is a similar example here which you can use as guidance (well, it is more complex then what you need but servers as an illustration).

Upvotes: 2

Related Questions