SafeArrayTypeMismatchException

We extended our legacy C++ DCOM application last week, and when the developer wrote the C#.Net end to call the new method, we were getting the error:

System.Runtime.InteropServices.SafeArrayTypeMismatchException

The developer that had added the method stated it worked, and pointed to his Delphi test app that worked happily.

Reviewing the method code it all looked fine. Single stepping through the code there where no problems.

The help for this exception says:

The exception thrown when the type of the incoming SAFEARRAY does not match the type specified in the managed signature.

But as we are dynamically calling the method like this:

objAddType = Type.GetTypeFromProgID("DCOM_OBJECT_NAME.COMPANY_CLASS_A");
objAdd = Activator.CreateInstance(objAddType);

object[] input = {};

object result = objAddType.InvokeMember("MethodName", BindingFlags.InvokeMethod, null, objAdd, input);

There was no was no signature.

This is for this Method:

VARIANT CompanyClassAObject::MethodName(void)
{
  VARIANT vaResult;
  VariantInit(&vaResult);

  SAFEARRAY* sfa = GetSafeArray();

  vaResult.vt = VT_UI1 | VT_ARRAY;
  vaResult.parray = sfa;

  return vaResult;
}

with the body of GetSafeArray looked like:

SAFEARRAYBOUND sfabounds[1];
sfabounds[0].lLbound = 0;
sfabounds[0].cElements = bytes_needed;
SAFEARRAY *sfa = SafeArrayCreate(VT_I1, 1, sfabounds);
if(sfa)
{
  void *data;
  if(SafeArrayAccessData(sfa, &data) == S_OK)
  {
    memcpy(data, buffer, bytes_needed);
    SafeArrayUnaccessData(sfa);

    delete buffer;
    return sfa;
  }
}

The problem ended up being that the SafeArray is created as VT_I1 type but when it is put into the variant type it was typed as VT_UI1.  So the .Net runtime was picking up the conflict and correctly complaining, and once you know what the error is, the exception message make sense.  Funny that!

Setting the SafeArrayCreate to use VT_UI1 and every thing worked.

Comments:

Stu 2009-08-12 01:42:46

lol its like some jepardy thing, knowing the answer knows the question but knowing the question doesnt mean you know the answer! aaargh. I hate that kind of debugging.


Simeon 2009-08-12 09:42:55

Exactly, at the start of the day we were reading the exception and scratching our heads, at the end of the day it seemed nice and concise, only problem is it didn’t help us get to the other side.

I guess it’s the classic problem of people in the know unable to write for people not in the know.