简体   繁体   中英

Using a managed c# dll inside an unmanaged c++ dll

How does an unmanaged c++ .dll know where the location of a managed c# .dll is?

Some context: I have a c++ .dll that imports a type library (.tlb) and inside one of the c++ functions, I instantiate a pointer to the functions inside the c# .dll. Then, using that pointer, I can call the c# functions in c++. I would like to know how c++ .dll know where the c# .dll is? Further, is there a better way to do this type of coding?

Does the .tlb need to be in the same directory as the c# .dll?

One way to accomplishing the above is to register the C# dll file with the Microsoft Windows Registry using the regasm command. This command EXE is included with distributions of Visual Studios. An example use of the command follows:

regasm NameofC#DLL.dll /tlb:NameofC#DLL.tlb

Once you have registered it in the registry you will need to install it to the global assembly cache (GAC) using the gacutil command. This is also included with distributions of Visual Studios. An example use of the command follows:

gacutil /i NameofC#DLL.dll

Once these steps are completed your C++ code will be able to find the C# dll assuming your DLL files are constructed similar to the following:

[C#]

using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace MyNameSpace
{
    /// <summary>
    /// Interface for C++ DLL. This exposes the functions used inside the dll
    /// Make sure the return types, function names, and argument types match the class
    /// </summary>
    [ComVisible(true)]
    [Guid("CBA208F2-E43B-4958-97C7-C24EA5A213DE")]
    public interface IMyClass
    {
        int Function1();
        int Function2();
    }

    [ClassInterface(ClassInterfaceType.None)]
    [Guid("579091E6-83A1-4aa5-89A7-F432AB2A57E3")]
    [ComVisible(true)]
    public class MyClass : IMyClass
    {
        public MyClass()
        {
            //Constructor
        }

       public int Function1()
        {
            //Do something in C#

            return an integer;
        }

        public int Function2()
        {
            //Do something else in C#

            return an integer;
        }
    }//End Class MyClass
}//End namespace MyNameSpace

Everywhere you see a GUID being used, that is a randomly generated global identifier used to identify your C# code. This number can be randomly generated using the GUID creation tool provided with Visual Studios under the "Tool menu" and the "Create GUID" option. Select Registry format and press "New GUID". Then just press copy and paste it where the GUID needs to be (Remove the brackets!)

[C++]

#include <windows.h>
#include "stdafx.h"
#include <cstdlib>
#pragma warning (disable: 4278)
#import <mscorlib.tlb> raw_interfaces_only
#include <stdio.h>
//This path needs to be valid at compile time. The file does not need to be there in runtime when using the DLL after compile.
#import "C:\\...\\NameofC#DLL.tlb" no_namespace named_guids

extern "C" _declspec(dllexport) int _Function1()
{   
        int result = 0;
    IMyClass *CSharpInterface = NULL;

    //Open interface to C#
    CoInitialize(NULL);
    HRESULT hr = CoCreateInstance(CLSID_MyClass, NULL, CLSCTX_INPROC_SERVER,
                                  IID_IMyClass, reinterpret_cast<void**>(&CSharpInterface));

    //Call Function1 C# method
    result = CSharpInterface->Function1();

    //Close interface
    CoUninitialize();

    //Return result
    return result;
}

The required TLB file at compile time can be generated using the tlbexp command also included with visual studios.An example use of the command follows:

tlbexp NameofC#DLL.dll

If you do not specify a path it will default to the following path:

C:\\Program Files\\Microsoft Visual Studio 9.0\\VC

There a several places you can mess this up and the C# DLL call will fail.

Regards,

SeaMossDesign

Maybe I'm missing something, but you can create a custom CLR host and invoke a method from C# without pointer. Check ICLRRuntimeHost::ExecuteInDefaultAppDomain out.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM