Re: status of nio version
Josh Passenger <[email protected]> Thu, 2 Jun 2005 09:35:17 +1000
| Newsgroups | gmane.comp.windows.devel.jawin |
|---|---|
| Message-ID | <[email protected]> |
All sounds good Roger,
Josh
>There are a number of issues which I would like to know if the changes
>adversely affect anyone.
>
>0) All current marshalling functionality remains available while new
>functionality is added.
>
>1) Is it a problem for anyone if the IdentityManager uses the IUnknown
>interface to work with the Jawin classes that implement it instead of
>the COMPtr directly? The COMPtr can still be instantiated by the
>IdentityManager but requires a cast when returned or used in arguments.
>The reason for the change is to allow other implementations to be
>obtained via the IUnknown interface rather than only extending COMPtr
>which at this time does not permit the object to extend anything else.
>For example a new visual component OLEControl extends
>javax.swing.JWindow and implements IUnknown, IOleControl, IDispatch, etc.
>
>2) The Jawin Type Browser employs the Saxon XSLT transformer and
>upgrades the code generating stylesheets to XSLT 2.0 and XPath 2.0
>capability. Very little Type Browser code changes. We will include the
>saxon jars and license in the downloads and next releases and remove Xalan.
>
>3) Everything I am doing is aimed at speed and seamless bridging. The
>member id from the function description will be used instead of passing
>a String with the function name to the new nio native calls and then
>converting to a BSTR and calling the method to get the member id to
>pass to the IDispatch invoke. The Jawin Type Browser is updated to
>provide the xml output with the member id. The vtableoffset will be
>used for virtual function events and callbacks. Is there any reason
>relying on the member id from the tlb's would be problematic? I am
>imitating what I see when a OleControl is dropped into a Visual C++
>project.
>
>This eliminates
> CComBSTR meth;
> meth.Attach(JNIComUtil::jstobs(env, jmeth));
> DISPID dwDispID;
> HRESULT hr = disp.GetIDOfName(meth, &dwDispID);
> if (SUCCEEDED(hr)) {
>
>from every call.
>
>4) Creating a OleControlStub for all the new marshalling and leaving
>the GenericStub as is.
>
>5) Am providing an invoke method for every type of return( similar to
>the way JNI is organized). The stylesheets will pick the right one when
>generating code.
>invokeVoidMethod
>invokeIntMethod
>...
>invokeObjectMethod
>
>These eliminate the need for
> return MarshalAllocator::allocateByteArray(env,
>javaOut.getMem(), javaOut.getPos());
>and replaces this with the direct application of the return Variant such as
> return retVar.lVal;
>for integer returning methods.
>
>6) The argument list for every Jawin native invocation call is being
>reduced to jint dwDispID, jobjectArray argArray, jint peer, jint unknown.
>dwDispID = member ID
>argArray = array of java.nio.ByteBuffer's. One for each argument and
>each contains a direct memory access to Variant.
>
>example:
>
>JNIEXPORT jint JNICALL
>Java_org_jawin_marshal_OleControlStub_invokeIntMethod
> (JNIEnv* env, jobject obj, jint dwDispID, jobjectArray argArray, jint
>peer, jint unknown)
>
>Notice the instString is gone which eliminates
>
> JNIComUtil::jstostr(env, instString, str);
> IStreamOnMemory instructions(str.c_str(), str.length() + 1);
>...
> Transform tin(env, &br, javaIn, instructions, comIn, NULL);
>...
> //write retval into stream
> Transform tret(env, &br, result, instructions, javaOut, NULL);
> //write out params into stream
> Transform tout(env, &br, comOut, instructions, javaOut, NULL);
>The direct access to the ByteBuffer variants eliminates
> IStreamOnMemory javaIn(request, requestSize, env);
> jint stackSizeWithRet = stackSize + 1;
>
> // Allocate memory for variants
> size_t vntsSize = sizeof(VARIANT) * stackSizeWithRet;
> VARIANT* vnts = (VARIANT*)MarshalAllocator::SafeMalloc(vntsSize,
>NULL); // should we pass the BatchReleaser?
> for (int i = 0; i < stackSizeWithRet; ++i) {
> ::VariantInit(vnts + i);
> }
> OStreamOnMemory comIn(vnts, vntsSize, true, true);
>...
> IStreamOnMemory result((byte*)comIn.getMem() +
>stackSize*sizeof(VARIANT), sizeof(VARIANT));
> IStreamOnMemory comOut((byte*)comIn.getMem(),
>stackSize*sizeof(VARIANT));
>with
> int arrayLength=env->GetArrayLength(argArray);
> VARIANTARG* pVar=new VARIANTARG[arrayLength];
> for(int i=0;i<arrayLength;i++)
> {
>
>pVar[i]=((VARIANT*)env->GetDirectBufferAddress(env->GetObjectArrayElement(argArray,
>(jint)i)))[0];
> }
> VARIANT retVar;
>The marshalling code is simplified to
>JNIEXPORT jint JNICALL
>Java_org_jawin_marshal_OleControlStub_invokeIntMethod
> (JNIEnv* env, jobject obj, jint dwDispID, jobjectArray argArray, jint
>peer, jint unknown)
>{
> long result;
> se_translator translator;
> try {
> int arrayLength=env->GetArrayLength(argArray);
> VARIANTARG* pVar=new VARIANTARG[arrayLength];
> for(int i=0;i<arrayLength;i++)
> {
>
>pVar[i]=((VARIANT*)env->GetDirectBufferAddress(env->GetObjectArrayElement(argArray,
>(jint)i)))[0];
> }
> VARIANT retVar;
> CComPtr<IDispatch> cpUnk;
> getUnknown(IID_IDispatch, peer, unknown, (IUnknown**) &cpUnk);
> CComDispatchDriver disp(cpUnk);
> IOleControl* olectl=NULL;
> cpUnk->QueryInterface(IID_IOleControl, (void **)&olectl);
> HRESULT hr;
> DISPID dispidPut = DISPID_VALUE;//DISPATCH_METHOD;
> DISPPARAMS dispparams;// = { pVar, NULL,
>(int)stackSize+1, 0};
> memset(&dispparams, 0, sizeof(dispparams));
> dispparams.rgvarg=pVar;
> //dispparams.rgdispidNamedArgs=&dispidPut;
> dispparams.cArgs=arrayLength;
> //dispparams.cNamedArgs=1;
> EXCEPINFO excepInfo;
> unsigned int argErr;
> //IDispatch* idisp=(IDispatch*)disp;
> hr = ((IDispatch*)olectl)->Invoke(dwDispID, IID_NULL,
>LOCALE_USER_DEFAULT, DISPATCH_METHOD, &dispparams, &retVar, &excepInfo,
>&argErr);
> //hr = disp.InvokeN((int)dwDispID, pVar, arrayLength,
>&retVar);
> olectl->Release();
> JNI_HR(hr);
> return retVar.lVal;
> }
> HANDLE_WIN32_EXCEPTIONS()
> HANDLE_JNI_EXCEPTIONS()
> return 0;
>}
>Note: Still experimenting with which invoke to use. Having difficulty
>with coclass, GUIDs, CLSIDs, catastrophic failures, etc.:-(
>New functionality needs to be added when the COM constructs and arg or
>changes it's dimension(s). But notice each arg can be handled
>independently without the need to rearrange a sometimes huge linear byte
>marshalling scheme around; expending and contracting for each changing
>argument. Now for such any argument it will be possible to natively
>construct a java.nio.ByteBuffer and fill it with an appropriate Variant
>where the type is already known by the Java arg.
>
>7) New put and get calls for the DISPATCH_PROPERTYGET and
>DISPATCH_PROPERTYPUT types of invokes. Again similar to JNI there will
>be multiple property invocations such as:
>putInt
>putDouble
>...
>putObject
>...
>getInt
>getDouble
>...
>getObject
>
>Again to eliminate decision making during runtime. All things that can
>be decided from the type info during the Type Browser and stylesheet
>phase will be used to eliminate runtime decisions and instructions.
>
>
>8) On the Java side of Jawin a new set of xslt's are being developed to
>create the interface layer. The interface layer will be larger and
>specific but will no longer call the methods in the Variant class or use
>the org.jawin.io stream classes(NakedByteStream,
>LittleEndianInputStream, LittleEndianOutputStream) A typical interface
>method will look like:
> public int IntegerTest(int index) throws COMException
> {
> java.nio.ByteBuffer[] bba=new java.nio.ByteBuffer[1];
> java.nio.ByteBuffer bb=java.nio.ByteBuffer.allocateDirect(16);
> bb.order(java.nio.ByteOrder.nativeOrder());
>
>bba[0]=bb.putShort((short)VarTypes.VT_I4).putShort((short)0).putShort((short)0).putShort((short)0).putInt(index);
> return invokeIntMethod((int)0x01, bba);
>
> }
>
>
>9) The JAWT functionality allows a visible Ole Control window to be
>painted onto the surface of a java.awt.Canvas in a javax.swing.JWindow.
>createControl and paint methods are being added to implement visible
>painting.
>
>10) still testing how to get a generic C++ callback function to employ
>for every virtual function in the vtable. When we have it, from it we
>can call the coclasses Java interface methods where the user can write
>their Java implementation. Any howto information on this part would be
>greatly appreciated.
>
>Any thoughts, ideas, foreseeable troubles with the refactoring and
>applying nio are appreciated.
>
>-Roger