Community
Participate
Working Groups
I've got a variant of type VT_VARIANT | VT_ARRAY. VT_ARRAY means that there is a pointer to the array in the data, Unfortunately SWT Variant does not support VT_ARRAY and does not give access to that pointer. In Variant.setData it would need to add code similar to the code for VT_BYREF to save the pointer in a field.
Created attachment 20964 [details] A modified Variant.java file which handles variants of type SafeArray. All the modifications made to the original Variant.java file have been tagged with "Added by BCO" / "End - Added by BCO". This is how I use the class ('commandArray' being a 2D-array of simple type variants): Variant.SafeArray safeArray = commandArray.getSafeArray(); int safeArrayPtr = 0; for (int i=0; i<safeArray.rgsabound[0].cElements; i++) { safeArrayPtr = safeArray.pvData + 16*i; Variant var = new Variant(); var.setSafeArray(safeArrayPtr); Variant.SafeArray safeArray2 = var.getSafeArray(); int safeArrayPtr2 = 0; for (int j=0; j<safeArray2.rgsabound[0].cElements; j++) { safeArrayPtr2 = safeArray2.pvData + 16*j; Variant var2 = new Variant(safeArrayPtr2); var2.setSafeArray(safeArrayPtr2); if (var2.getType() == OLE.VT_BSTR) System.out.print("\"" + var2.getString() + "\" "); else if (var2.getType() == OLE.VT_I4) System.out.print(var2.getInt() + " "); else if (var2.getType() == OLE.VT_BOOL) System.out.print(var2.getBoolean() + " "); else System.err.print("<type=" + var2.getType() + "> "); } System.out.println(); // carriage return }
Find attached a proposition to handle variants of type SafeArray (VT_ARRAY|VT_*).
Bertrand, thank you for the patch. Unfortunately, the solution requires new API and 1) we are API frozen so I would need to get the Eclipse API review committee to grant permission for the change and 2) this is not the way I would like to see the API of Variant evolve. Regarding 2, I do not want to expose a class like SafeArray and SafeArrayBounds. I would prefer to have API like Variant.get/setIntArray(), Variant.get/setStringArray() or perhaps more generically Variant.get/setVariantArray().
Hello, Is this going to be implementad anytime soon? I really need Browser widget that allows making POST requests and SAFEARRAY implementation (what ever it would look like) is needed to implement it.
Roland, I think what you are asking for is addressed in the following Snippet: http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.swt.snippets/src/org/eclip se/swt/snippets/Snippet186.java?rev=HEAD&content-type=text/vnd.viewcvs-markup What Bertrand has requested is a bit different - it is a VT_ARRAY that is not accessed by reference.
I would love to have the safearray support directly in the variant! Currently I'm using the (modified) code snippet, but that should not be the final solution for a product. Primary I need to transfer byte arrays.
Your bug has been moved to triage, visit http://www.eclipse.org/swt/triage.php for more info.
see bug 68194 comment 15, the patch in there implements support for returning or passing a safearray of IDispatch interfaces.
*** Bug 10977 has been marked as a duplicate of this bug. ***
(In reply to comment #3) > 2) this is not the way I > would like to see the API of Variant evolve. > > Regarding 2, I do not want to expose a class like SafeArray and > SafeArrayBounds. I would prefer to have API like Variant.get/setIntArray(), > Variant.get/setStringArray() or perhaps more generically > Variant.get/setVariantArray(). Would such API allow multi-dimensional arrays? Because I have an Ole component which has such API and I am stumbling on this bug! Would it be possible to get this in for the next version? I would definitely go for a milestone release and provide feedback if something gets there. Cheers, -Christopher
Created attachment 174211 [details] Modified (up-to-date) version of the patch, in-line with SWT 3.6 I ported the changes to the current version of SWT (3.6). The SafeArray class seems to point to the right data, but extracting that data is a pain. My test case is simply Excel, where I try to get the values of a Range. This is in the form of an array of variants, which themselves are BSTRs in my test case. I believe these could be of other types. Variant arrayVariant = //get property from Range. SafeArray safeArray = arrayVariant.getSafeArray(); int safeArrayPtr = safeArray.pvData; I empirically found that: String s = new Variant(safeArrayPtr + 8 + x*16, (short)(COM.VT_BYREF | COM.VT_BSTR)).getString()) where x = 1..4 for a 2D array of 2x2. I understand how to iterate for this kind of data, but I harcoded the BSTR type and I have no clue where I should read that VT type. It seems fFeature in SafeArray has the flag "FADF_HAVEVARTYPE" in my case, which means that "An array that has a VT type. When set, there will be a VT tag at negative offset 4 in the array descriptor that specifies the element type.". Having to walk negatively depending on obscure flags (and I tried without finding the type I was looking for) is insane. I also read this: "You should not attempt to manipulate a safearray or access an element manually; you should instead either use the API functions, or much better yet use the helper class CComSafeArray." Looking at the complexity of walking thoses structure manually, I think exposing the functions of one of these libraries is the way to go. Maybe the SafeArray class could hold the SafeArray structure (as it is now), but have methods that belong to one of these helper libraries, with type conversion where a VARIANT is internally returned for example.
I don't think the code in the patch is all that helpful, it reads the header information from the memory buffer (and makes it easily accessible by putting it in fields) but it doesn't provide any help to read the data (string, bytes, whatever is store in the array) from the array. In order to become an API the solution has the be complete (at least make easy to access the data in the array for primite types).
> In order to become an API the solution has the be complete (at least make easy > to access the data in the array for primite types). Yes I fully agree, but there exists such API as native libraries, and I don't think it is a good idea to re-write them in terms of low level calls. Everything I read basically said to not read by hand but use those libraries. I think what is necessary is simply to expose the methods of those native libaries in the SWT Java API. In such a case, we need to see a SafeArray class, which is actually the class to be manipulated by those new library-copied methods. It also makes sense to have a getter on the Variant instead of having to manipulate by hand a SAFEARRAY struct.
Is this library part of Windows ? Or has to be installed from third-parts ? If it is part of Windows, we can use it to implement our API. For example, we would add a Variant#getStringArray() which internally uses this library to do all the low level work returning a nice java String[] array to the caller.
> Is this library part of Windows ? Or has to be installed from third-parts ? I am not a Windows developer so I don't really know what is part of Windows or not. What I could find are these, there may be more: CComSafeArray Class (ATL) http://msdn.microsoft.com/en-us/library/3xzbsee8%28v=VS.80%29.aspx Array Manipulation Functions [Automation] http://msdn.microsoft.com/en-us/library/ms221145.aspx Is one of them a good candidate? If the first one is, then it looks like the way to go. Here is an examples of a Java API mapping for SafeArray (in Jacob), if it can help give ideas: http://jarvana.com/jarvana/view/net/sf/jacob-project/jacob/1.14.3/jacob-1.14.3-javadoc.jar!/api/com/jacob/com/SafeArray.html
I would avoid the first one as it uses ATL. The second one is fine. We should be able to use it, that said, you already did most of the job using low-level calls (meaning, we already know how to do that). It just need the code to get the elements (it should not be too bad, maybe easier than leraning how to use SafeArray* calls). As far as an API goes, maybe all we need to add is a getArray(), setArray() methods to be used when type == VT_ARRAY This would be similar to type == VT_BSTR, when getString/setString are used. (should also add constructor taking an array to consistent with all other types) getArray() would return a array of Variant objets. A Variant element of array can be another array (multi dimensional arrays). That is how I would try to implement this API. I know SafeArrays in COM and java arrays are not the same thing (SafeArrays have lower bounds/upper bounds and other things). I think it would be possible to map from one to another.
> I would avoid the first one as it uses ATL. You are the judge, as I said my knowledge is very limited and I have to say I really struggle to find the little information I communicated. > The second one is fine. > getArray() would return a array of Variant objets. A Variant element of array > can be another array (multi dimensional arrays). Well, a SafeArray can be an array of any type and, if I am not mistaken, of type by ref or not. I only tried with an array of Variant (by ref) so there is probably a bit more to do. It may not be that much as I guess reading a long or a String is probably similar to what the Variant is doing. > I know SafeArrays in COM and java arrays are not the same thing (SafeArrays > have lower bounds/upper bounds and other things). I think I read somewhere that lower bounds are always 0 in C, only VB may use different values (even negative!)
> Well, a SafeArray can be an array of any type and, if I am not mistaken, of > type by ref or not. Explorer uses an array of VT_UI1 as demonstrated in Snippet 186 (which ought to be converted to a more friendly API), and Excel ranges are arrays of VT_VARIANT (which themselves are of BTSTR, though I failed to find where that type is without using helper libraries). I think these are good first test cases. If there is any progress and if there is something to test, let me know and I would try it out with a nightly build. And of course if I can help progress on that issue somehow, please let me know how.
(In reply to comment #18) > If there is any progress and if there is something to test, let me know and I > would try it out with a nightly build. And of course if I can help progress on > that issue somehow, please let me know how. Right now I don't have time to work on OLE as I am (very) busy working on something else. I was hoping for someone from the community to collaborate with a patch which I would review and release.
> I was hoping for someone from the community to collaborate with > a patch which I would review and release. Yes, which is why I tried to contribute but fiddling with existing SWT mapped APIs is not enough and my Windows API and C knowledge is too rusty. I just hope it does not mean this feature is back to an endless sleep, because it is the missing piece for proper OLE support (in which my interface generator could be of great use for example).
This is a one-off bulk update. (The last one in the triage migration). Moving bugs from swt-triaged@eclipse to platform-swt-inbox@eclipse.org and adding "triaged" keyword as per new triage process: https://wiki.eclipse.org/SWT/Devel/Triage See Bug 518478 for details. Tag for notification/mail filters: @TriageBulkUpdate
This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet. As such, we're closing this bug. If you have further information on the current state of the bug, please add it and reopen this bug. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant. -- The automated Eclipse Genie.