8

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!

4

3 に答える 3

1

float 配列を渡す必要があります。COM 用語では、vt が VT_R4|VT_ARRAY に設定されたsa VARIANTを意味します。ドキュメントには、バリアントの配列 (VT_VARIANT |VT_ARRAY) を受け入れることができるとは記載されていないため、バリアントの配列は機能しない場合があります。Java では、パラメーターの型として float[] を使用できるはずです。そうでない場合は、いつでもWindows API を呼び出して、目的の型の安全な配列を構築できます。

于 2009-10-24T21:21:13.983 に答える
0

Variant の配列を作成し、それに float 配列の値を入力することの何が問題になっていますか?

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

本当に 1 つの引数 (float の配列) だけが必要な場合は、1 レベルの間接化を試すことができます。

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 の読み取りと書き込み」の例の後に、 の定数を使用して SAFEARRAY を作成してみることができますorg.eclipse.swt.internal.win32.OS。しかし、それはchar[]ただのようです。

関連する SAFEARRAY を作成するためのその他のインスピレーション源:

SafeArrayプロジェクト com4j のクラス(および などの関連クラスVariant)

于 2009-08-23T08:56:06.530 に答える
0

VARIANTには float 配列メンバーがないため、float[] を取るコンストラクターはないと思われます。

この作業を行うために必要なことは、float をSAFEARRAYにパックすることだと思います(いや、Java でフロートを作成する方法がわかりません)。

または、配列を raw ビットにシリアライズして、VARIANT 構造体の BYTE* メンバーを使用し、バイト数を持つ int を渡して、反対側で正確にデシリアライズできるようにすることもできます (これですべてだと思います)。同じプロセスとスレッドで、それ以外の場合は難しくなります)。

[id(20)]
void problemFoo([in] VARIANT bytes /* VT_BYREF|VT_UI1 */, [in] VARIANT byteCount /* VT_UI4 */);
于 2009-08-22T22:21:21.330 に答える