Доступ к SafeArray вариантов с помощью JNI - PullRequest
0 голосов
/ 07 сентября 2011

У меня есть VB6 ActiveX DLL с функциями, которые возвращают вариант. Вариант содержит массив вариантов узлов, каждый из которых содержит строковое имя и два массива данных (строковый и двойной). Я пытаюсь вернуть это Java-программе в качестве объекта задания через JNI.

Я могу получить доступ к внешнему массиву узлов, вызвав соответствующую функцию VB и сохранив результат Variant как SAFEARRAY. Он может получить доступ к измерению и получить нижнюю и верхнюю границы. Однако я не могу получить доступ к каждому узлу через SafeArrayGetElement () или SafeArrayAccessData (). Я всегда получаю исключение Invalid Argument.

1) Могу ли я передать или привести SAFEARRAY (или VARIANT) непосредственно к объекту задания без итерации по узлам в C ++?

2) Я использую неправильные параметры для получения данных SAFEARRAY? Нужно ли заранее указывать размер указателя доступа (var)?

    SAFEARRAY* outarr = t->VBFunction(&bstrparam).GetVARIANT().parray;

//Returns correct dimension (1)
    printf("JNI GetNodes_States: Got array, dimension %d\n", outarr->cDims);

//Returns correct bounds
    LONG lBound, rBound;
    SafeArrayGetLBound(outarr, 1, &lBound);
    SafeArrayGetUBound(outarr, 1, &rBound);
    printf("JNI GetNodes_States: Bounds [%d, %d]\n", lBound, rBound);

//Returns Invalid Argument error (hresult=0x80070057)
    //Gets first element
    LONG* indexArray = new LONG[outarr->cDims];
    for(unsigned short i=0; i<outarr->cDims; ++i)
        indexArray[i] = 0;
    _variant_t var;
    hresult = SafeArrayGetElement(outarr, indexArray, (void*)&var);

    if (SUCCEEDED(hresult)){
        printf( "JNI GetNodes_States: %s, %d\n", "", outarr->cDims);
    }
    else {
        printf( "JNI GetNodes_States Access Error:%X\n", hresult);
        outobj = NULL;
    }

    delete[] indexArray;

1 Ответ

1 голос
/ 09 сентября 2011

1) Могу ли я передать или привести SAFEARRAY (или VARIANT) непосредственно к заданию без итерации по узлам в C ++?

Абсолютно нет, я боюсь. Вы собираетесь пройтись по массиву, извлечь все необходимые значения и преобразовать каждое из них во что-то, что Java поймет.

2) Я использую неправильные параметры для получения данных SAFEARRAY? Нужно ли заранее указывать размер указателя доступа (var)?

Наиболее подозрительным аргументом является indexArray, для которого вы устанавливаете 0 для каждого измерения. Однако, если массив был создан Visual Basic, вполне возможно, что это массив на основе 1 вместо массива на основе 0, что сделало бы индекс 0 недопустимым.

Вот почему ваш код извлечения элементов должен обращать внимание на результаты SafeArrayGetLBound и SafeArrayGetUBound.

...