4

I am trying to call a function from a c# dll in a flutter desktop app,

In the C# dll I have,

using System;
using System.Runtime.InteropServices;

namespace MathLibrary
{
    // NOTE: I have set set [assembly: ComVisible(true)] in AssemblyInfo.cs

   [ComVisible(true)]
   [Guid("66DE2FB9-7A3B-4C33-AF26-9AD5EDD4C71F")]
   [InterfaceType(ComInterfaceType.InterfaceIsDual)]
   public interface IMathLibrary
   {
       [DispId(1)]
       string multiply(int a, int b);
    };
    
    [ComVisible(true)]
    [Guid("021E950E-3612-4FAD-9F15-F61632A95BD8")]
    [ClassInterface(ClassInterfaceType.None)]
    [ProgId("MathLibrary.MathCalc")]
    public class MathCalc : IMathLibrary
    {
        public string multiply(int a, int b)
        {
            return "Product is " + (a * b).ToString();
        }
    }
}

I used this repo as the base flutter app.

In the app I have used platform channel to communicate between dart and c++ code. In c++ code I am trying to call the c# function (in file windows/runner/custom_channel.cpp). After some googling, I came up with the following

First I added an import to the tlb file (had to add import to generated tlh file for IntelliSense to work)

#import "bin/MathLibrary.tlb" 
using namespace MathLibrary;

And the following function is supposed to call the c# function

CoInitialize(NULL);
MathLibrary::IMathLibraryPtr IcalcPtr;
HRESULT hr = ::CoCreateInstance(__uuidof(MathLibrary::MathCalc), NULL,
          CLSCTX_INPROC_SERVER,
          __uuidof(MathLibrary::IMathLibrary),
          (void**)&IcalcPtr);
           _bstr_t calcVal;
if (FAILED(hr) || IcalcPtr == nullptr) {
     // CoCreateInstance failed
     // THIS CONDITION IS MET
     (*resPointer)->Error("Cannot Create COM Object");
      return;
 }
//IcalcPtr->multiply(a, b, &calcVal);

calcVal = IcalcPtr->multiply(a, b); 

// not sure how to convert bstr to std::string
const char* calcStr((const char*) calcVal.GetBSTR());
c.assign(calcStr);
CoUninitialize();

The CoCreateInstance fails.

Since I have no experience with c++, I am confused,

  • what is IMathLibraryPtr(I didn't define in c#)
  • Intellisense showed that a and b in IcalcPtr->multiply(a, b) are long but I thought it would be int
  • When I make a release build do I need to include the tlb or dll
  • what is tlh file, it got generated during build and I got Intellisense support only if I add an import to that file

I would like to understand in general how to interact with c# com-interface from c++ and also how to make it work in my case. Sample code and document links would be helpful

1 Answers1

1

The problem was with the way the c# dll was built and not with the way it was called from c++. I had built the dll for "Any CPU" once I built it for x64 it worked.

  • 1
    Can you please write an article or something showing how you called .NET code from your Flutter app? Being able to leverage .NET code from a Flutter app is a huge need for many developers these days, and I didn't think it was possible until I found this answer on SO. – Lewis Cianci Apr 14 '22 at 23:50
  • @LewisCianci haven't written an article for com interop yet. But you can check my repository https://github.com/pratheeshrussell/flutter-platform-channel-windows/tree/master/com_interop .Remember the dll must be registered. In case you have trouble calling the platform channel in windows refer my article https://medium.com/p/7f4a837536b1 – Pratheesh Russell Apr 15 '22 at 06:56