Search code examples
c#comc++-clidllexportfirebreath

equivalent of a c# class in c /CLI when used as a parameter(managed) for a function in c /CLI


I have a c# file as below:

//MyHandler.cs
public **class MyHandler**
{
**Function1(IntPtr handle)**
{....}
Function2(MyImageHandler myImgHandler,int height,int width)
{....}
};

public **class MyImageHandler**
{
FunctionX(string imagePath,int height,int width)
{.....}
};

I am wrapping it using a c++/CLI wrapper dll which contains a header file as follows :

//IWrapper
#pragma once
#include<windows.h>
#include <string>

#ifdef MANAGEDWRAPPER_EXPORTS
#define DLLAPI  __declspec(dllexport)
#else
#define DLLAPI  __declspec(dllimport)
#pragma comment(lib,"D:\\MY\\MYY1\\Wrapper\\Debug\\MyFinalLibrary.lib")
#endif

class IWrapper
{
public:
   virtual DLLAPI void Function1(HWND  handle)=0;
   **virtual __stdcall void Function2(MyImageHandler myImageHandler,int width,int height)=0;**
};

** MyImageHandler is a managed class.so i am exporting it through __stdcall.Am i right in doing this? ** Now i have a header file implementing the above header file and then a cpp file as follows::

#include "Wrapper.h"
#include "IWrapper.h"
#include<vcclr.h>
#include <windows.h>
Function1(HWND handle)
{....}
Function2(MyImageHandler myImgHandler,int height,int weight)
{
//Here I need to typecast the MyImageHandler type to a managed handle
}

Solution

  • I just tested this on Visual Studio 2005, which worked:

    //Project: InteropTestCsLib, class1.cs
    namespace InteropTestCsLib
    {
        public class Class1
        {
            public int Add(int a, int b) { return a+b; }
        }
    }
    

    A C++/CLI project with an assembly reference to the C# one, and the project link option "Ignore import library" disabled (it was enabled by default)

    //Project: InteropTestCppCliLib, InteropTestCppCliLib.h
    namespace InteropTestCppCliLib {
    
        public ref class MyWrapper abstract sealed
        {
        public:
            static int Add(int a, int b);
        };
    }
    
    //Project: InteropTestCppCliLib, InteropTestCppCliLib.cpp
    namespace InteropTestCppCliLib {
    
    int MyWrapper::Add(int a, int b)
    {
        InteropTestCsLib::Class1^ obj = gcnew InteropTestCsLib::Class1();
        return obj->Add(a, b);
    }
    
    }
    
    //Free function, neither in a namespace nor class, but still managed code
    extern "C" int __stdcall MyWrapperAdd(int a, int b)
    {
        return InteropTestCppCliLib::MyWrapper::Add(a, b);
    }
    

    And the module-definition file (.def):

    LIBRARY "InteropTestCppCliLib"
    EXPORTS
        MyWrapperAdd
    

    And finally an empty native Win32 C/C++ project, with a project dependency on the C++/CLI DLL (or simply, a project that imports the import library it generated):

    /*Project: InteropTestUnmanagedApp, main.c*/
    #include <stdio.h>
    
    __declspec(dllimport) int __stdcall MyWrapperAdd(int a, int b);
    
    int main(void)
    {
        int x = 10;
        int y = 32;
        int result = MyWrapperAdd(x, y);
        printf("%d + %d = %d\n", x, y, result);
        return 0;
    }
    

    The C project called the C++/CLI one seamlessly.