【问题标题】:Accessing a SafeArray of Variants with JNI使用 JNI 访问变体的 SafeArray
【发布时间】:2011-09-07 19:07:29
【问题描述】:

我有一个 VB6 ActiveX DLL,其中包含返回 Variant 的函数。 Variant 包含一个节点变量数组,每个变量包含一个字符串名称和两个数据数组(字符串和双精度)。我正在尝试通过 JNI 将其作为作业返回给 Java 程序。

我可以通过调用适当的 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;

【问题讨论】:

  • 出于好奇,SafeArrayGetLBoundSafeArrayGetUBound 报告的界限是多少?

标签: com java-native-interface variant safearray


【解决方案1】:

1) 我可以将 SAFEARRAY(或 VARIANT)直接传递或强制转换到作业对象,而无需遍历 C++ 中的节点吗?

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

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

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

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

【讨论】:

  • 对于 9 项长数组,返回的边界是 0 和 8;我什至没有想过 VB 数组的索引不同。我尝试使用 1 的索引,但这导致了同样的错误。
猜你喜欢
  • 2010-10-12
  • 2012-05-14
  • 2014-05-15
  • 2017-01-11
  • 1970-01-01
  • 2012-08-03
  • 1970-01-01
  • 1970-01-01
  • 2022-11-11
相关资源
最近更新 更多