- Mixing Languages: Realizing the Promise of the CLR
- Building a Managed C++ Component with a C# Client
- Building a C# Component with a Managed C++ Client
- Building an Unmanaged C++ Client
- Summary
- Q&A
Building a Managed C++ Component with a C# Client
To illustrate how each different interaction scenario might work, you'll build not one, but three component/application combinations. The first one re-creates the component as a pure managed C++ component, and builds a C# and/or VB.NET client that accesses it. Next, you'll re-create the component using either C# or VB.NET, and access it using a managed C++ client. Finally, you'll access the C#/VB.NET component using an unmanaged C++ client.
Building the Managed C++ Component
To start the first of these projects, follow these steps:
Create a new Managed C++ Class Library project and name it MgdTaxCalc.
Open the MgdTaxCalc.h header file.
Replace the class name Class1 with the new class name, CTaxCalculator.
Add a new member function to the CTaxCalculator class (you'll need to expand the MgdTaxCalc namespace node in the Class View pane). Specify the function return type as double, the name as CalculateTaxes, and add two parameters. For the first parameter, specify the type as double and the name as dbPurchaseAmt. For the second parameter, specify the type as String* and the name as strCategory. Specify the function access as public.
Edit the function in the header file, adding the code in Listing 1.
Listing 1The CalculateTaxes Function
double CalculateTaxes(double dbPurchaseAmt, String* strCategory) { // Declare the array of tax categories String* strCategories[] = {S"food", S"clothing", S"music"}; // Declare the array of tax rates double dbRates[] = {0.0725, 0.0835, 0.081}; // Loop through the categories for (int i=0; i < 3; i++) { // Is this the category purchased? if (strCategory == strCategories[i]) { // Yes, calculate the taxes due return dbPurchaseAmt * dbRates[i]; } } // Couldn't find the category purchased, return 0 return 0; }
That's all for the managed C++ component. The code is basically the same as the unmanaged component, but it uses managed strings and returns the amount of taxes to charge as the result value.
Building the C# or VB.NET Client
The next step in this example adds either the C# or VB.NET client application to this solution. The client application duplicates the functionality from the managed C++ client application. To build this client, follow these steps:
In the Solution Explorer pane, select and right-click the solution node at the top of the tree. Select Add, New Project from the context menu.
Click either Visual Basic Projects or Visual C# Projects on the left side of the Add New Project dialog. Select Console Application on the right side of the dialog (this application type is available for both VB.NET and C# projects). If you are creating a Visual Basic project, name it VBClient. For a C# project, name it CSClient. Click OK to create the project.
In the Solution Explorer pane, select and right-click the References node in the new project you just created. Select Add Reference from the context menu.
In the Add Reference dialog, select the Projects tab. You should see your managed C++ component project (MgdTaxCalc) in the project list. Click the project and then click Select. Click OK to add the reference to the project.
If you created a C# project, open the Class1.cs file. If you created a VB project, open the Module1.vb file.
If you created a C# project, edit the main function, adding the code in Listing 2. If you created a VB project, edit the main function, adding the code in Listing 3.
Listing 2The C# Client Main Function
staticvoid Main(string[] args) { // // TODO: Add code to start application here // MgdTaxCalc.CTaxCalculator pGetTax = new MgdTaxCalc.CTaxCalculator(); double dbPurchaseAmt, dbTaxAmt, dbTotalDue; // Create the string for the category being purchased String strCategory = "clothing"; // Specify the purchase amount dbPurchaseAmt = 45.0; // Get the amount of taxes to collect dbTaxAmt = pGetTax.CalculateTaxes(dbPurchaseAmt, strCategory); if (dbTaxAmt > 0.0) { // Calculate the total due dbTotalDue = dbPurchaseAmt + dbTaxAmt; // Display the category being purchased Console.WriteLine(strCategory); // Display the purchase amount Console.Write("Purchase Amount = "); Console.WriteLine(dbPurchaseAmt.ToString("c")); // Display the tax due Console.Write(" Tax = "); Console.WriteLine(dbTaxAmt.ToString("c")); // Display the total amount Console.Write(" Total Due = "); Console.WriteLine(dbTotalDue.ToString("c")); } }
Listing 3The VB.NET Client Main Function
Sub Main() Dim pGetTax As MgdTaxCalc.CTaxCalculator pGetTax = New MgdTaxCalc.CTaxCalculator() Dim dbPurchaseAmt As Double Dim dbTaxAmt As Double Dim dbTotalDue As Double ' Create the string for the category being purchased Dim strCategory As String strCategory = "clothing" ' Specify the purchase amount dbPurchaseAmt = 45 ' Get the amount of taxes to collect dbTaxAmt = pGetTax.CalculateTaxes(dbPurchaseAmt, strCategory) If (dbTaxAmt > 0) Then ' Calculate the total due dbTotalDue = dbPurchaseAmt + dbTaxAmt ' Display the category being purchased Console.WriteLine(strCategory) ' Display the purchase amount Console.Write("Purchase Amount = ") Console.WriteLine(dbPurchaseAmt.ToString("c")) ' Display the tax due Console.Write(" Tax = ") Console.WriteLine(dbTaxAmt.ToString("c")) ' Display the total amount Console.Write(" Total Due = ") Console.WriteLine(dbTotalDue.ToString("c")) End If End Sub
In the Solution Explorer pane, select and right-click the client project that you created. Select Set as Startup Project from the context menu.
Now you should be able to compile and run your example application, producing the output in Figure 2. You can also repeat these steps to build the client application, using the other language than what you used (assuming that you have Visual Studio and not just Visual C++) so that you have both languages available for your use.
Figure 2 The running application.