2009-08-20 8 views
7

En mi aplicación Java SWT estoy alojando un control ActiveX de terceros. Estoy usando OleClientSite para hacer esto.interoperabilidad SWT de Java con COM: ¿poner un flotador [] en una variante?

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

Hay 2 pequeñas funciones que deseo llamar desde Java. Aquí están las definiciones de funciones COM:

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

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

Fácil, ¿no? Aquí está mi código de simulación:

// 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?]); 

El problema está en la última línea: cómo puedo pasar de una red de flotadores a la tercera objeto COM fiesta? AYUDA!

+0

Gracias por esas evaluaciones. Acabo de agregar un comentario que explica lo que encontré (y lo que hice * no *) sobre SAFEARRAY. – VonC

+0

Acaba de agregar otra referencia a un proyecto de Java que manipula 'SAFEARRAY'. Puede ser que podría ayudar. – VonC

+0

@Judah: el problema con '' VARIANT '' es que potencialmente puede ser cualquier cosa. Aún así, si es SAFEARRAY, ¿ha revisado http://j-integra.intrinsyc.com/support/com/doc/types/index.html y http://j-integra.intrinsyc.com/support/kb /Article.aspx?id=30430? – VonC

Respuesta

1

lo necesario para pasar una matriz de flotación. En términos COM, eso significa s a VARIANT con vt establecido en VT_R4 | VT_ARRAY. Es posible que una serie de variantes no funcione ya que el documento no dice que puede aceptar una matriz de variantes (VT_VARIANT | VT_ARRAY). En java, debería poder usar float [] como tipo de parámetro. Si no, siempre puede call the Windows API to construct a safe array of desired type.

+0

Gracias por la respuesta. He visto la "lectura y escritura en una matriz segura" en el artículo de Java al que enlazas. He adaptado ese código para trabajar con flotadores, y parece funcionar. Publicaré los resultados en breve. –

0

Sospecho que no hay ningún constructor que tome un flotador [] porque VARIANT s no tienen un miembro de la matriz flotante.

Creo que lo que tienes que hacer para que esto funcione es empacar tus carrozas en un SAFEARRAY (ick, y no tengo idea de cómo crear uno en Java).

Alternativamente, puede intentar serializar su matriz a bits sin procesar y usar el miembro BYTE * de la estructura VARIANT, y pasar un int que tiene el recuento de bytes para poder serializar con precisión en el otro lado (y yo asuma que todo esto está en el mismo proceso e hilo, de lo contrario se vuelve más difícil).

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

Mismo proceso, mismo subproceso, pero no hay problemaFoo (bytes, byteCount).El objeto COM es un control de terceros, uno que solo toma VARIANT y la documentación indica que debe pasar en una matriz flotante. –

+0

Bien. Bueno, con suerte esta o la otra respuesta te apunta en la dirección correcta. Tal vez contacte al proveedor y pregúnteles si tienen algún código de muestra de Java. –

+0

El proveedor ya no es compatible con este componente COM, por lo que no puedo obtener soporte de ellos. (Estamos tratando de pasar de este control de terceros, pero estas cosas llevan tiempo). Investigaré el miembro byte *. Si eso funciona, marcaré el tuyo como la respuesta correcta. –

0

¿Qué tiene de malo crear una matriz de variante y llenarla con los valores de la matriz de flotación?

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

Si lo que realmente necesita sólo un argumento (un conjunto de flotador), puede probar con un nivel de indirección:

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; 

Si el simple enfoque no funciona y sí es necesario un SAFEARRAY, podría intentar crear uno después del ejemplo "Reading and writing to a SAFEARRAY", usando las constantes de org.eclipse.swt.internal.win32.OS. Pero parece que solo para char[].

Otra fuente de inspiración para la creación de la SAFEARRAY relevante:

class SafeArray of project com4j (y su clase asociada, como Variant)

+0

Gracias, no se me ocurrió que podía enviar una serie de variantes. Lo intentaré y te responderé. –

+0

Con respecto a SAFEARRAY, no creo que necesite un SAFEARRAY, ya que COM IDL especificará cuándo lo necesita, ¿no? He visto IDL de funciones que requieren SAFEARRAY; este particular IDL dice que necesito una variante. De todas formas, intentaré esto y te responderé. –

+0

En realidad, ahora no estoy tan seguro; en realidad puede ser un SAFEARRAY. Hmmmm –

Cuestiones relacionadas