Skip to content

Commit

Permalink
support [in] SAFEARRAY* and [out,retval] SAFEARRAY*
Browse files Browse the repository at this point in the history
  • Loading branch information
viruscamp committed Jul 1, 2014
1 parent 6d3150f commit c48219e
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 5 deletions.
27 changes: 26 additions & 1 deletion native/invoke.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,28 @@ jobject Environment::invoke( void* pComObject, ComMethod method, jobjectArray ar
ffi_types[i + 1] = &ffi_type_pointer;
ffi_values[i + 1] = &c_args[i].v_ptr;
break;


case cvSAFEARRAY_byRef:
SAFEARRAY** ppsa = NULL;
if(arg==NULL) {
c_args[i].v_ptr = NULL;
} else if(env->IsSameObject(env->GetObjectClass(arg),com4j_Holder)) {
// if it's a holder, convert its value, and prepare the unmarshaller
// we don't know the inner type of array,
// if we know that by add a paramemnt to the function, we could use
// umn = new SafeArrayUnmarshaller<safearray::BasicArrayXducer<short>>(env, NULL);
jobject o = jholder(arg)->get(env);
unm = new SafeArrayUnmarshaller<safearray::SafeArrayXducer>(env, static_cast<jarray>(o));
add( new OutParamHandler( jholder(arg), unm ) ); // after the method call unmarshal it back to SAFEARRAY
ppsa = static_cast<SAFEARRAY**>(unm->addr());
} else {
error(env,__FILE__,__LINE__,"unable to convert the given object to SAFEARRAY*");
return NULL;
}
c_args[i].v_ptr = ppsa;
ffi_types[i + 1] = &ffi_type_pointer;
ffi_values[i + 1] = &c_args[i].v_ptr;
break;

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

case cvSAFEARRAY:
retUnm = new SafeArrayUnmarshaller<safearray::SafeArrayXducer>(env,NULL);
break;

default:
error(env,__FILE__,__LINE__,"unexpected conversion type: %d",retConv);
return NULL;
Expand Down
23 changes: 23 additions & 0 deletions native/unmarshaller.h
Original file line number Diff line number Diff line change
Expand Up @@ -171,3 +171,26 @@ class VariantUnmarshaller : public Unmarshaller {
return &v;
}
};

template < class XDUCER >
class SafeArrayUnmarshaller : public Unmarshaller {
SAFEARRAY* psa;
public:
SafeArrayUnmarshaller( JNIEnv* env, jarray i ) {
psa = NULL;
if(i!=NULL)
psa = XDUCER::toNative(env,i);
}

virtual void* addr() {
return &psa;
}

virtual jarray unmarshal( JNIEnv* env ) {
return XDUCER::toJava(env,psa);
}

virtual ~SafeArrayUnmarshaller() {
SafeArrayDestroy(psa);
}
};
6 changes: 3 additions & 3 deletions runtime/src/main/java/com4j/ComMethod.java
Original file line number Diff line number Diff line change
Expand Up @@ -242,9 +242,9 @@ static NativeType getDefaultConversion(Type t) {
if(Buffer.class.isAssignableFrom(c))
return NativeType.PVOID_ByRef;
}
// if(v instanceof GenericArrayType){
// return NativeType.SafeArray_ByRef;
// }
if(v instanceof GenericArrayType){
return NativeType.SafeArray_ByRef;
}
}
if( p.getRawType()==Iterator.class ) {
return NativeType.ComObject;
Expand Down
20 changes: 19 additions & 1 deletion tlbimp/src/main/java/com4j/tlbimp/TypeBinding.java
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,24 @@ public static TypeBinding bind( Generator g, IType t, String nameHint ) throws B
}
}

ISafeArrayType at = comp.queryInterface(ISafeArrayType.class);
if(at!=null) {
// T=SAFEARRAY(...)
IType comp2 = at.getComponentType();

IPrimitiveType compPrim2 = comp2.queryInterface(IPrimitiveType.class);
if( compPrim2!=null ) {
TypeBinding r = primitiveTypeBindings.get(compPrim2.getVarType());
if(r!=null) {
return new TypeBinding("Holder<"+r.javaType+"[]>", NativeType.SafeArray, true );
}
}
TypeBinding tb = TypeBinding.bind(g, comp2, null);
if(tb.nativeType == NativeType.VARIANT){
return new TypeBinding("Holder<Object[]>", NativeType.SafeArray, true);
}
}

// a few other random checks
String name = getTypeString(ptrt);
if( name.equals("_RemotableHandle*") ) {
Expand Down Expand Up @@ -225,7 +243,7 @@ private static String getTypeString(IType t) {

ISafeArrayType sa = t.queryInterface(ISafeArrayType.class);
if (sa != null) {
return "SAVEARRAY(" + getTypeString(sa.getComponentType()) + ")";
return "SAFEARRAY(" + getTypeString(sa.getComponentType()) + ")";
}

return "N/A";
Expand Down

0 comments on commit c48219e

Please sign in to comment.