Search code examples
c#c++dllv8node-gyp

Importing a class from a c# dll into a c++ app


I need to import a dll made in c# from c++ All the examples I found import a single function from a dll, but as far as I know, you cannot export a single function from c# without exporting the whole class (I'm a bit of a c# newbie though)

I am using node gyp to compile it (I'm building a node module for my web app using v8)

Here is my c# code:

using System;
using System.IO;
using System.Runtime.InteropServices;

[ComVisible(true)]
public class Hello 
{
    public static void Main() 
    {
        Console.WriteLine("Hello World!");
        string createText = "Hello World" + Environment.NewLine;
        File.WriteAllText(".\\asd.txt", createText);
    }
}

And this is my c++ header file:

#ifndef ASDLIB_H
#define ASDLIB_H
#define ASD_IMPORT __declspec(dllimport)
#define STDCALL __stdcall

class ASD_IMPORT Hello{
    public:
         STDCALL static void ASD_IMPORT Main();
};

#endif // ASDLIB_H

Solution

  • I normally do this kind of stuff by creating a static C++ CLR Wrapper Lib.

    These are the steps I'm normally using (although I don't use it very often):

    Here minimal example with using Visual Studio:

    1. Create managed C# .NET library Project

    Let name it HelloLibManaged with one file Hello.cs and following content:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace HelloLibManaged
    {
        public class Hello
        {
            public void Print()
            {
                System.Console.WriteLine("Hello from Managed Lib");
            }
        }
    }
    

    Build this lib with x86 or x64 , just dont Any CPU

    2. Create a new C++ CLR static lib project within same solution. Let's name it HelloLibCpp

    • Add a reference to HelloLibManaged project via Project->Add Reference

    • Remove automatic created existing .h/.cpp files from Project, and create these 2 files:

    HelloUnmanaged.h

    #pragma once
    
    namespace hello_managed {
    
        class Hello
        {
        public:
            void Print();
        };
    }
    

    and

    HelloUnmanaged.cpp:

    #include "HelloUnmanaged.h"
    
    namespace hello_managed
    {
    
        void Hello::Print()
        {
            HelloLibManaged::Hello^ hello = gcnew HelloLibManaged::Hello();
            hello->Print();
        }
    
    }
    

    Und Project Properties -> General specify static lib. In the Build settings specify x86 / x64 - use the same build type as building Managed lib from Step 1.

    Now you can build the dll and use it in your other unmanaged C++ projects.

    For more advanced stuff, like return types and methods with parameters you have to do Type-Marshalling between managed/unmanaged code. There are many resources online with more information about Type-Conversion between managed/unmanaged code. Keyword: Marshaling.