none
C#-Klassenaufruf aus WIN32 heraus

    Allgemeine Diskussion

  • Hallo

    Ich rufe aus einer win32-Anwendung heraus eine Klasse in C## auf. von 2.0 bis 3.5 funktioniert alles noch. Ab 4.0 funktionieren der Aufruf nicht mehr. Hat sich hier in der COM-Schnittstelle vielleicht etwas geändert?

    int CallManagedFunction(char* szAsseblyName, char* szClassNameWithNamespace,char* szMethodName, int iNoOfParams, VARIANT * pvArgs, VARIANT * pvRet)
    {
        CComPtr<ICorRuntimeHost>    pRuntimeHost;
        CComPtr<_AppDomain>            pDefAppDomain;

        try
        {
            //Retrieve a pointer to the ICorRuntimeHost interface
            HRESULT hr = CorBindToRuntimeEx(
                NULL,    //Specify the version of the runtime that will be loaded.
                L"wks",//Indicate whether the server or workstation build should be loaded.
                //Control whether concurrent or non-concurrent garbage collection
                //Control whether assemblies are loaded as domain-neutral.
                STARTUP_LOADER_SAFEMODE | STARTUP_CONCURRENT_GC,
                CLSID_CorRuntimeHost,
                IID_ICorRuntimeHost,
                //Obtain an interface pointer to ICorRuntimeHost
                (void**)&pRuntimeHost
                );

            if (FAILED(hr)) return hr;

            //Start the CLR
            hr = pRuntimeHost->Start();

            CComPtr<IUnknown> pUnknown;

            //Retrieve the IUnknown default AppDomain
            hr = pRuntimeHost->GetDefaultDomain(&pUnknown);
            if (FAILED(hr)) return hr;

            hr = pUnknown->QueryInterface(&pDefAppDomain.p);
            if (FAILED(hr)) return hr;

            CComPtr<_ObjectHandle> pObjectHandle;


            _bstr_t _bstrAssemblyName(szAsseblyName);
            _bstr_t _bstrszClassNameWithNamespace(szClassNameWithNamespace);

            //Eine Instanz der Assembly erzeugen
            hr = pDefAppDomain->CreateInstance(
                _bstrAssemblyName,
                _bstrszClassNameWithNamespace,
                &pObjectHandle
                );
            if (FAILED(hr)) return hr;

            CComVariant VntUnwrapped;
            hr = pObjectHandle->Unwrap(&VntUnwrapped);
            if (FAILED(hr)) return hr;

            if (VntUnwrapped.vt != VT_DISPATCH)
                return E_FAIL;

            CComPtr<IDispatch> pDisp;
            pDisp = VntUnwrapped.pdispVal;

            DISPID dispid;

             DISPPARAMS dispparamsArgs = {NULL, NULL, 0, 0};
            dispparamsArgs.cArgs = iNoOfParams;
            dispparamsArgs.rgvarg = pvArgs;


            WCHAR Buffer[1024];
            MultiByteToWideChar(0, 0, szMethodName,-1,Buffer, sizeof(Buffer) / 2);
            BSTR MethodName = SysAllocString(Buffer);

            hr = pDisp->GetIDsOfNames (
                IID_NULL,
                &MethodName,
                1,
                LOCALE_SYSTEM_DEFAULT,
                &dispid
                );
            SysFreeString(MethodName);

            if (FAILED(hr)) return hr;

            //Invoke the method on the Dispatch Interface
            // Methode über das Dispatch Interface aufrufen
            hr = pDisp->Invoke (
                dispid,
                IID_NULL,
                LOCALE_SYSTEM_DEFAULT,
                DISPATCH_METHOD,
                &dispparamsArgs,
                pvRet,
                NULL,
                NULL
                );
            if (FAILED(hr)) return hr;

            pRuntimeHost->Stop();

            return ERROR_SUCCESS;
        }
        catch(_com_error e)
        {
            //Fehlerbehandlung
            printf("\nError\n");
            return ERROR_INVALID_PARAMETER;
        }
    }

    Danke schon einmal im vorraus

    Gruß Ralf

    Montag, 14. Januar 2013 13:21

Alle Antworten