Hi

 

I am having a problem invoking static methods on a .NET class via COM.

 

The class I am using looks like [see 1 below]. The assembly has a strong
name and is registered in the GAC. I can instantiate an instance of Class1
using late binding in C++.

 

The invoke code I am using is ripped directly from Adam Nathan's '.NET and
COM' interop book [see 2 below]

 

When using the invoke code on a system type such as "System.AppDomain" and
its static member function "GetCurrentThreadId" everything works fine. If I
try and invoke "Test" on "ClassLibrary2.Class1" then I fail to generate the
Type object for ClassLibrary2.Class1 (see line marked with a *** in [2])

 

Am I missing attributes on my class or assembly to allow static member
invocation via COM interop? Or am I doing something else real stupid? 

 

Thanks for any help,

 

tom

 

[1]

using System;

using System.Runtime.InteropServices;

 

namespace ClassLibrary2

{

      [Guid("2F756616-C5D1-429c-A10C-0FAB0FF22887")]

      public class Class1

      {

            public Class1()

            {

            

            }

 

      public static string Test()

      {

         return "Hullo world!!";

      }

}

   }

}

 

[2]

 

HRESULT CDispatchWrapper::InvokeStaticMember(BSTR typeName, BSTR memberName,


                           mscorlib::BindingFlags memberType, 

                           SAFEARRAY* parameters, VARIANT* retVal)

{

   HRESULT hresult;

   IUnknown* pUnk = NULL;

   mscorlib::_Object* pObj = NULL;

   mscorlib::_Type* pType = NULL;

   mscorlib::_Type* pTypeOfType = NULL;

   mscorlib::_Type* pDesiredType = NULL;

   VARIANT typeNameParam;

   VARIANT getTypeRetVal;

   VARIANT nullObject;

   SAFEARRAY* psa;

   LONG index;

   BSTR getTypeName = SysAllocString(L"GetType");

 

   VariantInit(&typeNameParam);

   VariantInit(&getTypeRetVal);

   VariantInit(&nullObject);

 

   // Instantiate a dummy class just so we can get a System.Type instance

   hresult = CoCreateInstance(mscorlib::CLSID_Object, NULL, 

    CLSCTX_INPROC_SERVER, IID_IUnknown, (void **)&pUnk);

   if (FAILED(hresult)) goto cleanup;

 

   // Get the _Object interface so we can call GetType

   hresult = pUnk->QueryInterface(mscorlib::IID__Object, (void**)&pObj);

   if (FAILED(hresult)) goto cleanup;

 

   // Call _Object.GetType

   hresult = pObj->GetType(&pType);

   if (FAILED(hresult)) goto cleanup;

 

   // Call the instance Type.GetType method (inherited from Object)

   // in order to get the type for System.Type rather than the type for

   // System.Object

   hresult = pType->GetType(&pTypeOfType);

   if (FAILED(hresult)) goto cleanup;

 

   // Prepare a 1-element array containing the passed-in type name

   // to pass to the static Type.GetType method

   psa = SafeArrayCreateVector(VT_VARIANT, 0, 1);

   typeNameParam.vt = VT_BSTR;

   typeNameParam.bstrVal = typeName;

   index = 0;

   hresult = SafeArrayPutElement(psa, &index, &typeNameParam);

   if (FAILED(hresult)) goto cleanup;

 

   // Invoke the static Type.GetType method using reflection on the

   // type for System.Type in order to get the desired type

   nullObject.vt = VT_EMPTY;

   hresult = pTypeOfType->InvokeMember_3(getTypeName,

    (mscorlib::BindingFlags)(mscorlib::BindingFlags_InvokeMethod |
mscorlib::BindingFlags_Public | 

    mscorlib::BindingFlags_Static |
mscorlib::BindingFlags_FlattenHierarchy), NULL, 

    nullObject, psa, &getTypeRetVal);

    // *** the above line returns S_OK, but getTypeRetval is VT_EMPTY
instead of VT_DISPATCH.

 

   if (FAILED(hresult)) goto cleanup;

 

   // Get the _Type interface so we can call the static InvokeMember

   // method on the desired type to invoke the desired static member

   hresult = getTypeRetVal.punkVal->QueryInterface(mscorlib::IID__Type, 

    (void**)&pDesiredType);

   if (FAILED(hresult)) goto cleanup;

 

   // Invoke the desired static member

   pDesiredType->InvokeMember_3(memberName,
(mscorlib::BindingFlags)(memberType |

    mscorlib::BindingFlags_Public | mscorlib::BindingFlags_Static | 

    mscorlib::BindingFlags_FlattenHierarchy), NULL, nullObject, parameters, 

    retVal);

   if (FAILED(hresult)) goto cleanup;

 

   cleanup:

   if (pUnk) pUnk->Release();

   if (pObj) pObj->Release();

   if (pType) pType->Release();

   if (pTypeOfType) pTypeOfType->Release();

   if (pDesiredType) pDesiredType->Release();

   if (getTypeName) SysFreeString(getTypeName);

   SafeArrayDestroy(psa);

   VariantClear(&typeNameParam);

   VariantClear(&getTypeRetVal);

   VariantClear(&nullObject);

 

   return hresult;

};

 

 


===================================
This list is hosted by DevelopMentor�  http://www.develop.com
Some .NET courses you may be interested in:

NEW! Guerrilla ASP.NET, 17 May 2004, in Los Angeles
http://www.develop.com/courses/gaspdotnetls

View archives and manage your subscription(s) at http://discuss.develop.com

Reply via email to