0

I'm trying to figure out how to make a C# DLL work with C++. I have gotten a simple function like int add(int a, int b) { return a + b; } to work, however I can't seem to get a string function to work. I know that string in C# is different from any type in C++, but here is the code and I would like to know what exactly is going on.

C#:

namespace DllTest
{
    [ComVisible(true)]

    public interface MyClass
    {
        string doSomething(string a);
    }

    [ComVisible(true)]
    [ClassInterface(ClassInterfaceType.None)]  

    public class Class1 : MyClass
    {
        public string doSomething(string a)
        {
            return a;
        }
    }
}

C++:

#include <iostream>
#include <Windows.h>
#import "C:\Users\Archie\Documents\Visual Studio 2013\Projects\DllTest\DllTest\bin\Debug\DllTest.tlb" raw_interfaces_only

using namespace DllTest;

int main()
{
    CoInitialize(NULL);

    MyClassPtr obj;
    obj.CreateInstance(__uuidof(Class1));

    std::cout << obj->doSomething("Hello");

    CoUninitialize();
}

When I call the function, I actually get an error saying that I am missing a parameter, which shouldn't be the case. Here's what pops up when I peek the definition of doSomething while working with C++:

virtual HRESULT __stdcall doSomething (
    /*[in]*/ BSTR a,
    /*[out,retval]*/ BSTR * pRetVal ) = 0;

It looks like the function is actually returning a long now, with two wchar_t-type parameters. I guess I'm really just wondering why this is happening. Is it even possible to accomplish what I'm trying to do? To make a string function in C# and call it in C++?

Archie Gertsman
  • 1,601
  • 2
  • 17
  • 45
  • you may look at this link http://pragmateek.com/using-c-from-native-c-with-the-help-of-ccli-v2/ as it explain what need to convert C# string to ansi string (call of StringToHGlobalAnsi) – Fab Feb 25 '16 at 03:44

1 Answers1

0

Welcome to COM and the nightmarish syntax and contortions you have to go through to do something simple, like returning a string value.

Every call to COM will return an HRESULT regardless of what your implementing call is trying to return. This is typlically 0 to indicate success. Any other value indicates a failure. You've probably seen these insane 0x80001234 kind of values in error messages for Windows - they are the HRESULT error codes.

As you can see from the definition of doSomething in C++, you have to give the function 2 parameters.

  1. The string to pass in as the calling argument.
  2. A pointer to a BSTR that will receive the result.

Then adjust your code accordingly

MyClassPtr obj;
obj.CreateInstance(__uuidof(Class1));
BSTR result = 0;

DWORD hr = obj->doSomething("Hello", &result);

if (hr != 0)
{ //handle error conditions.
}
else
{ // we've had success ...

   _bstr_t str(result);

   std::cout << str;
}
Jens Meinecke
  • 2,904
  • 17
  • 20
  • Thank you. When I tried this, my error handle was to print out "Bad", and it did. So what can be wrong then? – Archie Gertsman Feb 25 '16 at 04:23
  • Rather than merely printing `Bad` you might try printing out the value of `hr` in hexadecimal form (see (http://stackoverflow.com/questions/5100718/integer-to-hex-string-in-c) ) and then do a google on the hex value (include the term `0x` before the hex value in your google search) – Jens Meinecke Feb 25 '16 at 05:19
  • You might also look at this [Common HRESULT Values](https://msdn.microsoft.com/en-us/library/windows/desktop/aa378137(v=vs.85).aspx) to see whether your value is one of these. – Jens Meinecke Feb 25 '16 at 05:24
  • Okay, thanks. Now it seems to get passed the error, but what is printed out is blank. Any ideas as to why that might be? – Archie Gertsman Feb 25 '16 at 05:36