Skip to content

Commit

Permalink
Merge pull request #642 from SevenOf9Sleeper/com_proxy_allows_ellipsis
Browse files Browse the repository at this point in the history
feature #630: use of ellipsis/varargs in COM methods
  • Loading branch information
dblock committed Apr 23, 2016
2 parents 4ba3c1d + a7fb1e5 commit 4b7421c
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 4 deletions.
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ Features
* [#621](https://github.com/java-native-access/jna/pull/621): Added TYPEFLAGS-constants for `wTypeFlags` in `com.sun.jna.platform.win32.OaIdl.TYPEATTR` - [@SevenOf9Sleeper](https://github.com/SevenOf9Sleeper).
* [#625](https://github.com/java-native-access/jna/pull/625): Make conversion to/from java to/from VARIANT in `com.sun.jna.platform.win32.COM.util.Convert` more flexible and dependable - [@matthiasblaesing](https://github.com/matthiasblaesing).
* [#639](https://github.com/java-native-access/jna/pull/639): Add getloadavg() to OS X and Unix - [@dbwiddis](https://github.com/dbwiddis).
* [#642](https://github.com/java-native-access/jna/pull/642): COM calls with variable number of arguments (varargs) are now supported - [@SevenOf9Sleeper](https://github.com/SevenOf9Sleeper).

Bug Fixes
---------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
package com.sun.jna.platform.win32.COM.util;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Proxy;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;
Expand Down Expand Up @@ -51,7 +52,6 @@
import com.sun.jna.platform.win32.COM.util.annotation.ComProperty;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.ptr.PointerByReference;
import java.lang.reflect.InvocationTargetException;

/**
* This object acts as the invocation handler for interfaces annotated with
Expand Down Expand Up @@ -232,12 +232,13 @@ public Object invoke(final Object proxy, final java.lang.reflect.Method method,

ComMethod meth = method.getAnnotation(ComMethod.class);
if (null != meth) {
Object[] fullLengthArgs = unfoldWhenVarargs(method, args);
int dispId = meth.dispId();
if(dispId != -1) {
return this.invokeMethod(returnType, new DISPID(dispId), args);
return this.invokeMethod(returnType, new DISPID(dispId), fullLengthArgs);
} else {
String methName = this.getMethodName(method, meth);
return this.invokeMethod(returnType, methName, args);
return this.invokeMethod(returnType, methName, fullLengthArgs);
}
}

Expand Down Expand Up @@ -401,6 +402,21 @@ public <T> T invokeMethod(Class<T> returnType, DISPID dispID, Object... args) {
return (T) Convert.toJavaObject(result, returnType, factory, false, true);
}

private Object[] unfoldWhenVarargs(java.lang.reflect.Method method, Object[] argParams) {
if (null == argParams) {
return null;
}
if (argParams.length == 0 || !method.isVarArgs() || !(argParams[argParams.length - 1] instanceof Object[])) {
return argParams;
}
// when last parameter is Object[] -> unfold the ellipsis:
Object[] varargs = (Object[]) argParams[argParams.length - 1];
Object[] args = new Object[argParams.length - 1 + varargs.length];
System.arraycopy(argParams, 0, args, 0, argParams.length - 1);
System.arraycopy(varargs, 0, args, argParams.length - 1, varargs.length);
return args;
}

@Override
public <T> T queryInterface(Class<T> comInterface) throws COMException {
assert COMUtils.comIsInitialized() : "COM not initialized";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
import com.sun.jna.Pointer;
import static org.junit.Assert.*;

import java.io.File;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
Expand All @@ -41,8 +43,53 @@ interface Application extends IUnknown {

@ComMethod
void Quit(boolean SaveChanges, Object OriginalFormat, Boolean RouteDocument);

@ComMethod
public void Quit(Object... someArgs);

@ComMethod(dispId = 0x00000183)
public float PointsToPixels(float points, Object... someArgs);

@ComProperty(dispId = 0x00000006)
public Documents getDocuments();
}


@ComInterface(iid = "{0002096C-0000-0000-C000-000000000046}")
public interface Documents extends IDispatch {
@ComMethod
public _Document Add(Object template, Object newTemplate, Object documentType, Object visible);

@ComMethod
public _Document Add(Object... someArgs);
}

@ComInterface(iid = "{0002096B-0000-0000-C000-000000000046}")
public interface _Document extends IDispatch {
@ComMethod
public void SaveAs(Object fileName, Object fileFormat, Object lockComments, Object password,
Object addToRecentFiles, Object writePassword, Object readOnlyRecommended, Object embedTrueTypeFonts,
Object saveNativePictureFormat, Object saveFormsData, Object saveAsAOCELetter, Object encoding,
Object insertLineBreaks, Object allowSubstitutions, Object lineEnding, Object addBiDiMarks);

@ComMethod
public void SaveAs(Object... someArgs);
}

public enum WdSaveFormat implements IComEnum {
wdFormatDocument(0), wdFormatText(2), wdFormatRTF(6), wdFormatHTML(8), wdFormatPDF(17);

private long _value;

private WdSaveFormat(long value) {
_value = value;
}

@Override
public long getValue() {
return _value;
}
}

@ComObject(progId="Word.Application")
interface MsWordApp extends Application {
}
Expand Down Expand Up @@ -116,4 +163,27 @@ public void accessWhilstDisposing() {

}

@Test
public void testVarargsCallWithoutVarargParameter() {
MsWordApp comObj = this.factory.createObject(MsWordApp.class);

// call must work without exception:
float f = comObj.PointsToPixels(25.3f);
comObj.Quit();
}

@Test
public void testVarargsCallWithParameter() {
MsWordApp comObj = this.factory.createObject(MsWordApp.class);

Documents documents = comObj.getDocuments();
_Document myDocument = documents.Add();

String path = new File(".").getAbsolutePath();
myDocument.SaveAs(path + "\\abcdefg", WdSaveFormat.wdFormatPDF);
comObj.Quit();

boolean wasDeleted = new File("abcdefg.pdf").delete();
assertTrue(wasDeleted);
}
}

0 comments on commit 4b7421c

Please sign in to comment.