使用 JNI 访问 SafeArray 变体

发布于 2024-12-03 13:50:56 字数 1449 浏览 1 评论 0原文

我有一个 VB6 ActiveX DLL,其中包含返回变体的函数。 Variant 包含一个节点 Variants 数组,每个 Variants 包含一个字符串 Name 和两个数据数组(字符串和双精度)。我试图通过 JNI 将其作为 jobobject 返回到 Java 程序。

我可以通过调用适当的 VB 函数并将 Variant 结果存储为 SAFEARRAY 来访问外部节点数组。它可以访问维度并获取下限和上限。但是,我无法通过 SafeArrayGetElement() 或 SafeArrayAccessData() 访问每个节点。我总是收到无效参数异常。

1) 我是否可以将 SAFEARRAY(或 VARIANT)直接传递或转换为 jobobject,而无需迭代 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;

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 array 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;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

伤感在游骋 2024-12-10 13:50:56

1) 我可以将 SAFEARRAY(或 VARIANT)直接传递或转换为 jobobject,而不用迭代 C++ 中的节点吗?

恐怕绝对不是。您将遍历该数组,提取所有必要的值,并将每个值转换为 Java 可以理解的内容。

2) 我是否使用了错误的参数来获取 SAFEARRAY 数据?访问指针(var)的大小是否需要预先分配?

最可疑的参数是 indexArray,您将其每个维度设置为 0。但是,如果该数组是由 Visual Basic 创建的,则很可能它是基于 1 的数组而不是基于 0 的数组,这会使索引 0 非法。

这就是为什么您的元素提取代码需要注意 SafeArrayGetLBoundSafeArrayGetUBound 的结果。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文