Skip to content

Commit c48219e

Browse files
committed
support [in] SAFEARRAY* and [out,retval] SAFEARRAY*
1 parent 6d3150f commit c48219e

File tree

4 files changed

+71
-5
lines changed

4 files changed

+71
-5
lines changed

native/invoke.cpp

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -393,7 +393,28 @@ jobject Environment::invoke( void* pComObject, ComMethod method, jobjectArray ar
393393
ffi_types[i + 1] = &ffi_type_pointer;
394394
ffi_values[i + 1] = &c_args[i].v_ptr;
395395
break;
396-
396+
397+
case cvSAFEARRAY_byRef:
398+
SAFEARRAY** ppsa = NULL;
399+
if(arg==NULL) {
400+
c_args[i].v_ptr = NULL;
401+
} else if(env->IsSameObject(env->GetObjectClass(arg),com4j_Holder)) {
402+
// if it's a holder, convert its value, and prepare the unmarshaller
403+
// we don't know the inner type of array,
404+
// if we know that by add a paramemnt to the function, we could use
405+
// umn = new SafeArrayUnmarshaller<safearray::BasicArrayXducer<short>>(env, NULL);
406+
jobject o = jholder(arg)->get(env);
407+
unm = new SafeArrayUnmarshaller<safearray::SafeArrayXducer>(env, static_cast<jarray>(o));
408+
add( new OutParamHandler( jholder(arg), unm ) ); // after the method call unmarshal it back to SAFEARRAY
409+
ppsa = static_cast<SAFEARRAY**>(unm->addr());
410+
} else {
411+
error(env,__FILE__,__LINE__,"unable to convert the given object to SAFEARRAY*");
412+
return NULL;
413+
}
414+
c_args[i].v_ptr = ppsa;
415+
ffi_types[i + 1] = &ffi_type_pointer;
416+
ffi_values[i + 1] = &c_args[i].v_ptr;
417+
break;
397418

398419
default:
399420
error(env,__FILE__,__LINE__,"unexpected conversion type: %d",convs[i]);
@@ -466,6 +487,10 @@ jobject Environment::invoke( void* pComObject, ComMethod method, jobjectArray ar
466487
retUnm = new VariantUnmarshaller();
467488
break;
468489

490+
case cvSAFEARRAY:
491+
retUnm = new SafeArrayUnmarshaller<safearray::SafeArrayXducer>(env,NULL);
492+
break;
493+
469494
default:
470495
error(env,__FILE__,__LINE__,"unexpected conversion type: %d",retConv);
471496
return NULL;

native/unmarshaller.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,3 +171,26 @@ class VariantUnmarshaller : public Unmarshaller {
171171
return &v;
172172
}
173173
};
174+
175+
template < class XDUCER >
176+
class SafeArrayUnmarshaller : public Unmarshaller {
177+
SAFEARRAY* psa;
178+
public:
179+
SafeArrayUnmarshaller( JNIEnv* env, jarray i ) {
180+
psa = NULL;
181+
if(i!=NULL)
182+
psa = XDUCER::toNative(env,i);
183+
}
184+
185+
virtual void* addr() {
186+
return &psa;
187+
}
188+
189+
virtual jarray unmarshal( JNIEnv* env ) {
190+
return XDUCER::toJava(env,psa);
191+
}
192+
193+
virtual ~SafeArrayUnmarshaller() {
194+
SafeArrayDestroy(psa);
195+
}
196+
};

runtime/src/main/java/com4j/ComMethod.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -242,9 +242,9 @@ static NativeType getDefaultConversion(Type t) {
242242
if(Buffer.class.isAssignableFrom(c))
243243
return NativeType.PVOID_ByRef;
244244
}
245-
// if(v instanceof GenericArrayType){
246-
// return NativeType.SafeArray_ByRef;
247-
// }
245+
if(v instanceof GenericArrayType){
246+
return NativeType.SafeArray_ByRef;
247+
}
248248
}
249249
if( p.getRawType()==Iterator.class ) {
250250
return NativeType.ComObject;

tlbimp/src/main/java/com4j/tlbimp/TypeBinding.java

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,24 @@ public static TypeBinding bind( Generator g, IType t, String nameHint ) throws B
125125
}
126126
}
127127

128+
ISafeArrayType at = comp.queryInterface(ISafeArrayType.class);
129+
if(at!=null) {
130+
// T=SAFEARRAY(...)
131+
IType comp2 = at.getComponentType();
132+
133+
IPrimitiveType compPrim2 = comp2.queryInterface(IPrimitiveType.class);
134+
if( compPrim2!=null ) {
135+
TypeBinding r = primitiveTypeBindings.get(compPrim2.getVarType());
136+
if(r!=null) {
137+
return new TypeBinding("Holder<"+r.javaType+"[]>", NativeType.SafeArray, true );
138+
}
139+
}
140+
TypeBinding tb = TypeBinding.bind(g, comp2, null);
141+
if(tb.nativeType == NativeType.VARIANT){
142+
return new TypeBinding("Holder<Object[]>", NativeType.SafeArray, true);
143+
}
144+
}
145+
128146
// a few other random checks
129147
String name = getTypeString(ptrt);
130148
if( name.equals("_RemotableHandle*") ) {
@@ -225,7 +243,7 @@ private static String getTypeString(IType t) {
225243

226244
ISafeArrayType sa = t.queryInterface(ISafeArrayType.class);
227245
if (sa != null) {
228-
return "SAVEARRAY(" + getTypeString(sa.getComponentType()) + ")";
246+
return "SAFEARRAY(" + getTypeString(sa.getComponentType()) + ")";
229247
}
230248

231249
return "N/A";

0 commit comments

Comments
 (0)