tags:

views:

50

answers:

2

Starting from this example: http://support.microsoft.com/kb/828736 I have tried to add a test function in my C# DLL which takes strings as parameters. My C# DLL code is as follows:

namespace CSharpEmailSender
{
   // Interface declaration.
   public interface ICalculator
   {
       int Add(int Number1, int Number2);
       int StringTest(string test1, string test2);
   };

// Interface implementation.
public class ManagedClass : ICalculator
{
    public int Add(int Number1, int Number2)
    {
        return Number1 + Number2;
    }

    public int StringTest(string test1, string test2)
    {
        if (test1 == "hello")
            return(1);

        if (test2 == "world")
            return(2);

        return(3);
    }
}

I then register this DLL using regasm. I use it in my C++ app like so:

using namespace CSharpEmailSender;
using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
// Initialize COM.
HRESULT hr = CoInitialize(NULL);

// Create the interface pointer.
ICalculatorPtr pICalc(__uuidof(ManagedClass));

long lResult = 0;
long lResult2 = 0;

pICalc->Add(115, 110, &lResult);
wprintf(L"The result is %d", lResult);

pICalc->StringTest(L"hello", L"world", &lResult2);
wprintf(L"The result is %d", lResult2);

// Uninitialize COM.
CoUninitialize();

return 0;

}

After running this, lResult is correct (with value of 225), but lResult2 is zero. Any idea what I'm doing wrong?

A: 

Without trying to compile this, perhaps the interop expects the string to be of BSTR type. Can you try the following?

pICalc->StringTest(CComBSTR(L"hello"), CComBSTR(L"world"), &lResult2);

OR

pICalc->StringTest(::SysAllocString(L"hello"), ::SysAllocString(L"world"), &lResult2); 
Igor Zevaka
I'm using Visual C++ Express 2008 - seems I need to get the platform SDK just to use CComBSTR :(
Martin
No need, just for testing purposes, do `::SysAllocString(L"hello")`.
Igor Zevaka
With your 2nd suggestion I get this error:cannot convert parameter 1 from 'BSTR' to 'SAFEARRAY *'
Martin
Interesting, I am out of suggestions then :(
Igor Zevaka
Don't know if I tried some changes and forgot to re-regasm, but it now works properly with your 2nd suggestion!
Martin
A: 

You're using == for string comparison inside StringTest, which does reference comparison. This works (usually) in pure C# because all strings are interned, but strings passed through COM will not be reference-equal to their equivalent strings in C#. Try using Equals instead.

JSBangs
I don't think that's the case. Have a look here: http://msdn.microsoft.com/en-us/library/system.string.op_equality.aspx - **This operator is implemented using the Equals method, which means the comparands are tested for a combination of reference and value equality. This operator performs an ordinal comparison.**
Igor Zevaka