Java SWT 与 COM 互操作 - 将 float[] 放入变体中?

发布于 2024-08-01 23:04:04 字数 819 浏览 7 评论 0原文

在我的 Java SWT 应用程序中,我托管第 3 方 ActiveX 控件。 我正在使用 OleClientSite 来执行此操作。

// Ah, this works. :-)
OleAutomation comObject = new OleAutomation(...);

我想从 Java 调用 2 个简单的小函数。 以下是 COM 函数定义:

[id(5)]
void easyFoo([in] int blah);

[id(20)]
void problemFoo([in] VARIANT floatArray);

很简单,对吗? 这是我的假装代码:

// Ah, this works. :-)
OleAutomation comObject = new OleAutomation("Some3rdPartyControlHere");

// Call easyFoo(42). This works. :-)
int easyFooId = 5;
comObject.invoke(easyFooId, new Variant[] { new Variant(42) });

// Call problemFoo(new float[] { 4.2, 7.0 }). This doesn't work. :-(
int problemFooId = 20;
comObject.invoke(problemFooId, [ACK! What goes here?]);

问题在最后一行:如何将浮点数组传递给第 3 方 COM 对象? 帮助!

In my Java SWT application I'm hosting an 3rd party ActiveX control. I'm using OleClientSite to do this.

// Ah, this works. :-)
OleAutomation comObject = new OleAutomation(...);

There are 2 easy little functions I want to call from Java. Here are the COM function definitions:

[id(5)]
void easyFoo([in] int blah);

[id(20)]
void problemFoo([in] VARIANT floatArray);

Easy, right? Here's my pretend code:

// Ah, this works. :-)
OleAutomation comObject = new OleAutomation("Some3rdPartyControlHere");

// Call easyFoo(42). This works. :-)
int easyFooId = 5;
comObject.invoke(easyFooId, new Variant[] { new Variant(42) });

// Call problemFoo(new float[] { 4.2, 7.0 }). This doesn't work. :-(
int problemFooId = 20;
comObject.invoke(problemFooId, [ACK! What goes here?]);

The problem is on the last line: how do I pass a float array to the 3rd party COM object? HELP!

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

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

发布评论

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

评论(3

遗失的美好 2024-08-08 23:04:04

您需要传递一个浮点数组。 在 COM 术语中,这意味着 sa VARIANT 以及vt 设置为 VT_R4|VT_ARRAY。 变体数组可能不起作用,因为文档没有说它可以接受变体数组 (VT_VARIANT |VT_ARRAY)。 在java中你应该能够使用float[]作为参数类型。 如果没有,您可以随时 调用 Windows API 来构造安全数组所需类型

You need to pass a float array. In COM terms, that mean s a VARIANT with vt set to VT_R4|VT_ARRAY. An array of variants may not work as the document does not say it can accept an array of variants (VT_VARIANT |VT_ARRAY). In java you should be able to use float[] as the parameter type. If not you can always call the Windows API to construct a safe array of desired type.

荭秂 2024-08-08 23:04:04

我怀疑没有构造函数需要 float[] 因为 VARIANT s 没有浮点数组成员。

我认为要完成这项工作,您需要做的是将浮动打包到 SAFEARRAY (恶心;我不知道如何用 Java 创建一个)。

或者,您可以尝试将数组序列化为原始位并使用 VARIANT 结构的 BYTE* 成员,并传递一个具有字节数的 int,以便您可以在另一端准确地反序列化(我假设这就是全部)在同一进程和线程中,否则会变得更困难)。

[id(20)]
void problemFoo([in] VARIANT bytes /* VT_BYREF|VT_UI1 */, [in] VARIANT byteCount /* VT_UI4 */);

I suspect there is no constructor that takes a float[] because VARIANTs don't have a float array member.

I think what you need to do to make this work is pack up your floats into a SAFEARRAY (ick; and I have no idea how to create one in Java).

Alternatively, you may try serializing your array to raw bits and use the BYTE* member of the VARIANT struct, and pass an int that has the count of bytes so you can accurately de-serialize on the other side (and I assume this is all in the same process and thread, otherwise it gets harder).

[id(20)]
void problemFoo([in] VARIANT bytes /* VT_BYREF|VT_UI1 */, [in] VARIANT byteCount /* VT_UI4 */);
忘你却要生生世世 2024-08-08 23:04:04

创建 Variant 数组并用浮点数组值填充它有什么问题?

Variant[] problemFooArgs = new Variant[myFloats.length]; 
for( int i=0; i<myFloats.length; i++)
{
        problemFooArgs[i] = new Variant(myFloats[i]);
}

如果它确实只需要一个参数(浮点数组),您可以尝试一级间接:

Variant[] problemFooArgs = new Variant[1]; 
Variant[] myFooArgs = new Variant[1]; 
for( int i=0; i<myFloats.length; i++)
{
        myFooArgs [i] = new Variant(myFloats[i]);
}
problemFooArgs[0] = myFooArgs;

如果简单的方法不起作用并且您确实需要 SAFEARRAY,您可以尝试在示例“读取和写入 SAFEARRAY”,使用 org.eclipse.swt.internal.win32.OS。 但它似乎仅适用于 char[]

创建相关 SAFEARRAY 的其他灵感来源:

项目 com4j 的 SafeArray (及其关联的类,例如 Variant)

What's wrong with creating an array of Variant and filling it with your float array values?

Variant[] problemFooArgs = new Variant[myFloats.length]; 
for( int i=0; i<myFloats.length; i++)
{
        problemFooArgs[i] = new Variant(myFloats[i]);
}

If it really needs only one argument (an array of float), you could try one level of indirection:

Variant[] problemFooArgs = new Variant[1]; 
Variant[] myFooArgs = new Variant[1]; 
for( int i=0; i<myFloats.length; i++)
{
        myFooArgs [i] = new Variant(myFloats[i]);
}
problemFooArgs[0] = myFooArgs;

If the simple approach does not work and you do need a SAFEARRAY, you could try and create one after the example "Reading and writing to a SAFEARRAY", using the constants of org.eclipse.swt.internal.win32.OS. But it seems for char[] only.

Other source of inspiration for creating the relevant SAFEARRAY:

class SafeArray of project com4j (and its associated class, like Variant)

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