Вызов управляемого COM из неуправляемого кода: SAFEARRAY

0

У меня есть компонент COM, написанный на VB.net. Интерфейс для этого COM-компонента

Public Interface IEdge
    Function FooFunc() As Integer
    Function Exec(ByVal modelName As String, ByVal Params As Object()) As Object
    Sub Foo()
    Sub Fooint(ByVal a As Integer)
End Interface

Я использую библиотеку типов этого COM-компонента в Native C++, используя

#import "..\Edge.tlb" named_guids raw_interfaces_only

Код C++ для Main

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

    ICOMEdgePtr myEdge;
    HRESULT hRes =   myEdge.CreateInstance(CLSID_COMEdge);
    if (hRes == S_OK)
    {
        VARIANT lResult ;
        BSTR str;

        myEdge->Foo();
        myEdge->Fooint(1234);
        long abc = 0;
        myEdge->FooFunc(&abc);

        SAFEARRAYBOUND aBound[2];
        aBound[1].cElements = 2;
        aBound[1].lLbound = 0;
        SAFEARRAY* sf = SafeArrayCreate(VT_INT, 1, &aBound[1]);

        long index1=0;
        int val1=20;
        SafeArrayPutElement(sf, &index1, &val1);

        long index2=1;
        int val2=30;
        SafeArrayPutElement(sf, &index2, &val2);

        myEdge->Exec(L"Add", sf, &lResult);
        //Using lResult after this  
    }

    CoUninitialize (); 
    return 0;
}

Я могу FooFunc(), Foo(), Fooint().

Но я не могу вызвать функцию Exec, она не показывает никаких ошибок, об авариях не сообщается.

Для теста я использовал этот COM-компонент в VB.net (используя CreateObject(CLSID)), и Exec может быть вызван оттуда. Мне нужно вызвать это из Native C++.

Я подозреваю, что есть некоторые проблемы с SafeArray и Object(). Не определено ли определение интерфейса?

Я попытался использовать System.Array, <MarshalAs(UnmanagedType.SafeArray)> но ничто не решает проблему. Я поставил MsgBox() как первый оператор определения Exec чтобы я мог узнать, вызван ли Exec.

  • 2
    В этом коде отсутствует вся необходимая проверка ошибок. Что говорит вам, что вы сделали не так. SafeArray из VTINT соответствует только Integer () в VB.NET
  • 0
    @HansPassant Попытка сейчас для Integer () ... Фактический код C ++ имеет обработку исключений, но это не ловит ничего связанного с этим.
Показать ещё 1 комментарий
Теги:
com

1 ответ

1
Лучший ответ

Из предложений, предоставленных Hans Passant я могу использовать SAFEARRAY.

Я потребляю компонент COM на основе Dotnet в C++. Наконец, я изменил код C++, чтобы оставаться в безопасности с COM.

Я заменил VARIANT на CComVariant, BSTR с CComBSTR и SAFEARRAY с помощью CComSafeArray.

Теперь главный код выглядит так:

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

    ICOMEdgePtr myEdge;
    HRESULT hRes =   myEdge.CreateInstance(CLSID_COMEdge);
    if (hRes == S_OK)
    {
        CComVariant lResult ;
        CComSafeArray<VARIANT> arr(2,0);
        arr[0] = 20;
        arr[1] = 30;

        CComBSTR methodName;
        methodName = L"Add";

        myEdge->Exec(methodName, arr, &lResult);
        wprintf(L"The result is %d\n", lResult.intVal);
        //Using lResult after this
    }

    CoUninitialize (); 
    return 0;
}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню