Friday, February 8, 2013

How to call C# DLL from C++ DLL

This step-by-step post describes how to call a managed DLL from native C++ code. To do this, create a simple managed DLL by using Microsoft Visual C# .NET or Microsoft Visual C# 2008, and then call this managed DLL from native C++ code.

Requirements

This article assumes that you are familiar with the following topics:
  • Writing Component Object Model (COM) clients
  • COM interoperability in the Microsoft .NET Framework

The following list outlines the recommended hardware, software, network infrastructure, and service packs that you need:
  • Visual C# .NET or Visual C# 2008
  • Visual C++ .NET or Visual C++ 2008

Write a Managed DLL

To create a simple managed DLL that has a public method to add two numbers and return the result, follow these steps:
  1. Start Microsoft Visual Studio .NET or Microsoft Visual Studio 2005.
  2. On the File menu, point to New, and then click Project. The New Project dialog box opens.
  3. Under Project Types, click Visual C# Projects.

    Note In Visual Studio 2005, click Visual C# under Project Types.
  4. Under Templates, click Class Library.
  5. In the Name text box, type ManagedDLL, and then click OK.
  6. Open the Class1.cs file in Code view.
  7. To declare a public interface that has a method to add two numbers, add the following code to the Class1.cs file:

    // Interface declaration.
    public interface ICalculator
    {
        int Add(int Number1, int Number2);
    };
  8. To implement this public interface in a class, add the following code to the Class1.cs file:

    // Interface implementation.
    public class ManagedClass:ICalculator
    {
        public int Add(int Number1,int Number2)
            {
                return Number1+Number2;
            }
    }
  9. Click Start, and then point to Programs.
  10. If you are using Microsoft Visual Studio .NET 2003, point to Microsoft Visual Studio .NET 2003, and then point toVisual Studio .NET Tools. If you are using Microsoft Visual Studio .NET 2002, point to Microsoft Visual Studio .NET, and then point to Visual Studio .NET Tools. If you are using Visual Studio 2005, point to Microsoft Visual Studio 2005, and then point to Visual Studio 2005 Tools.
  11. If you are using Visual Studio .NET 2003, click Visual Studio .NET 2003 Command Prompt to open a Visual Studio .NET command prompt. If you are using Visual Studio .NET 2002, click Visual Studio .NET Command Prompt to open a Visual Studio .NET command prompt. If you are using Visual Studio 2005, click Visual Studio 2005 Command Promptto open a Visual Studio 2005 command prompt.
  12. To create a strong name for your class library, type the following command at the Visual Studio .NET command prompt:
    sn.exe -k MyKeyFile.SNK
  13. Copy the MyKeyFile.SNK file to your project folder.
  14. Double-click the AssemblyInfo.cs file to open the file in Solution Explorer.
  15. Replace the following lines of code in the AssemblyInfo.cs file

    [assembly: ComVisible(false)]
    [assembly: AssemblyDelaySign(false)]
    [assembly: AssemblyKeyFile("")]
    with the following.

    [assembly: ComVisible(true)] 
    [assembly: AssemblyDelaySign(false)] 
    [assembly: AssemblyKeyFile("..\\..\\MyKeyFile.SNK")]
  16. Press CTRL+SHIFT+B to generate the managed DLL.

Register the Managed DLL for Use with COM or with Native C++

To use the managed DLL with COM or with native C++, you must register the assembly information of your DLL in the Windows registry. To do this, follow these steps:
  1. Click Start, and then point to Programs.
  2. If you are using Microsoft Visual Studio .NET 2003, point to Microsoft Visual Studio .NET 2003, and then point toVisual Studio .NET Tools. If you are using Microsoft Visual Studio .NET 2002, point to Microsoft Visual Studio .NET, and then point to Visual Studio .NET Tools. If you are using Visual Studio 2005, point to Microsoft Visual Studio 2005, and then point to Visual Studio 2005 Tools
  3. If you are using Visual Studio .NET 2003, click Visual Studio .NET 2003 Command Prompt to open a Visual Studio .NET command prompt. If you are using Visual Studio .NET 2002, click Visual Studio .NET Command Prompt to open a Visual Studio .NET command prompt. If you are using Visual Studio 2005, click Visual Studio 2005 Command Promptto open a Visual Studio 2005 command prompt.
  4. At the Visual Studio .NET or Visual Studio 2005 command prompt, change the directory path of the directory that contains your managed DLL.
  5. To register the assembly information of your managed DLL in the Windows registry and to create a corresponding type library, run the following command at the Visual Studio .NET command prompt:
    RegAsm.exe ManagedDLL.dll /tlb:ManagedDLL.tlb /codebase

Call the Managed DLL from Native C++ Code

To call the managed DLL that you just created from native C++ code, follow these steps:
  1. Start Visual Studio .NET or Visual Studio 2005.
  2. On the File menu, point to New, and then click Project.
  3. If you are using Visual C++ .NET 2003, click Visual C++ Projects under Project Types, and then click Win32 Console Project under Templates. If you are using Visual C++ .NET 2002, click Visual C++ Projects under Project Types, and then click Win32 Project under Templates. If you are using Visual C++ 2005, click Visual C++ under Project Types, and then click Win32 Project under Templates
  4. In the Name text box, type CPPClient, and then click OK.
  5. If you are using Visual C++ .NET 2003 or Visual C++ 2005, click Finish. If you are using Visual C++ .NET 2002, clickApplication Settings, click Console Application, and then click Finish.
  6. Open the CPPClient.cpp file in Code view.
  7. To import the type library that RegAsm.exe generates, add the following code to the CPPClient.cpp file:

    // Import the type library.
    #import "..\ManagedDLL\bin\Debug\ManagedDLL.tlb" raw_interfaces_only
    Change the path of the type library if the path on your computer differs from this path.
  8. To declare the namespace to use, add the following code to the CPPClient.cpp file:

    using namespace ManagedDLL;
  9. To call the managed DLL, add the following code to the _tmain function:

    // 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();
    return 0;
  10. Press CTRL+F5 to run the application.

Complete Code Listing

Managed DLL

// Class1.cs
// A simple managed DLL that contains a method to add two numbers.
using System;

namespace ManagedDLL
{
 // Interface declaration.
    public interface ICalculator
    {
        int Add(int Number1, int Number2);
    };

    // Interface implementation.
 public class ManagedClass:ICalculator
 {
       public int Add(int Number1,int Number2)
            {
                return Number1+Number2;
            }
 }
}
C++ Client

// CPPClient.cpp: Defines the entry point for the console application.
// C++ client that calls a managed DLL.

#include "stdafx.h"
#include "tchar.h"
// Import the type library.

#import "..\ManagedDLL\bin\Debug\ManagedDLL.tlb" raw_interfaces_only
using namespace ManagedDLL;
int _tmain(int argc, _TCHAR* argv[])
{
    // 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\n", lResult);


    // Uninitialize COM.
    CoUninitialize();
    return 0;
}
Note You must add the common language runtime support compiler option (/clr:oldSyntax) in Visual C++ 2005 to successfully compile this code sample. To do this, follow these steps:
  1. Click Project, and then click ProjectName Properties.

    Note ProjectName represents the name of the project.
  2. Expand Configuration Properties, and then click General.
  3. Click to select Common Language Runtime Support, Old Syntax (/clr:oldSyntax) in the Common Language Runtime support project setting on the right pane, click Apply, and then click OK.

2 comments:

  1. Hi,

    In step 7 of Call the Managed DLL from Native C++ Code, the import is looking for .tlh file.
    what is that, any idea?

    ReplyDelete
    Replies
    1. It means, the import needs the header file .tlh.

      Regards
      Bharat

      Delete