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