开发者

Accessing a SafeArray of Variants with JNI

I have a VB6 ActiveX DLL with functions that return a Variant. The Variant contains an array of node Variants, each of which contains a string Name and two data arrays (string and double). I am attempting to return this to a Java program as a jobject through JNI.

I can access the outer arra开发者_如何转开发y of nodes by calling the appropriate VB function and storing the Variant result as a SAFEARRAY. It can access the dimension and get lower and upper bounds. However, I cannot access each node through SafeArrayGetElement() or SafeArrayAccessData(). I always get an Invalid Argument exception.

1) Can I pass or cast the SAFEARRAY (or VARIANT) directly to a jobject without iterating through the nodes in C++?

2) Am I using the wrong parameters to get the SAFEARRAY data? Does the size of the access pointer (var) need to be allocated beforehand?

    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) Can I pass or cast the SAFEARRAY (or VARIANT) directly to a jobject without iterating through the nodes in C++?

Absolutely not, I'm afraid. You're going to walk through the array, extract all the necessary values, and convert each of them to something that Java will understand.

2) Am I using the wrong parameters to get the SAFEARRAY data? Does the size of the access pointer (var) need to be allocated beforehand?

The most suspicious argument is indexArray, which you're setting to 0 for each dimension. However, if the array was created by Visual Basic it is quite possible that it is a 1-based array instead of a 0-based array, which would make an index of 0 illegal.

This is why your element-extraction code needs to pay attention to the results of SafeArrayGetLBound and SafeArrayGetUBound.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜