In one of the projects I am doing I needed to create the COM object that is going to be used from JavaScript. It is a well-known scenario - the JScript implementations lets programmer instantiate any COM object that is an ActiveX automation-enabled, i.e. it implements an IDispatch interface. Then, you can call any method or manipulate any property of the COM object. It looks nice and perfect as long as you are using simple data types - numbers, string. Still, there is no problem even to pass the object. Your property may be even visible as an object to the script - you may pass back the pointer to the IDispatch implementation of some object as the property and it can be treated in script almost like a native JScript object.
However, it no longer looks so bright when you need to pass to/from your COM object an array. The problem is that what you call an array in JavaScript is the completely different thing than what you call an array in your programming language you use to create your COM object. To complicate things more, an array in JScript, an array in ActiveX world and an array in "serious" programming languages like C++ or Delphi are different objects. In C, C++ and pascal it is, simply, the segment of memory which contains consecutive elements of the same certain type. In ActiveX world and Visual Basic which is set in this world, array refers to what is called variant arrays, safe arrays or VBArrays, which are bound inside the VARIANT type and are still, more or less, block of memory. On the other hand, in JScript, the array is the object that has its own properties (in fact one - length) and methods. It is not hard to guess that it is in no way compatible with safe arrays.
Your COM object will use safe arrays as it is a standard way in ActiveX. Let us, firstly, concentrate on returning arrays from the function. We will consider the object Some.Object that exposes the following method:[id(0x000002C0)]
which may have the following implementation in Delphi:
HRESULT GetSomeArray([out, retval] VARIANT *retArr );function TSomeObject.GetSomeArray : OleVariant;
In VBScript there would be no problem with dealing with the result of this function. In JScript, however, we get something which is not familiar - it is not an array as JScript understands it.
var
vals: array [0..2] of Variant;
begin
vals[0] := 'Hello';
vals[1] := 'World';
vals[2] := 'Dude';
Result := VarArrayOf(vals);
end;
Is there any way to convert safe arrays to JScript arrays? Fortunately, the answer is affirmative. JScript architects has provided the class VBArray which is the JScript front-end to safe arrays. We can manage it in the following way:var someObj = new ActiveXObject("Some.Object");
We have used here toArray() method to convert the VBArray to the JScript array. We could also use getItem() method to directly access element of the array. Note, that script engines, both JScript and VBScript have the limitation - they can only process safe array containing elements of type Variant. Therefore, even if you want to pass an array of strings, make the array's element to be of type Variant.
var arr = (new VBArray(someObj.GetSomeArray())).toArray();
alert(arr[0]);
OK, it was not so bad. But, what about passing an array to the function. Here, we encounter the real problem. We will solve it in the next post.
Monday, August 13, 2007
JScript arrays and COM objects, part 1
Subscribe to:
Post Comments (Atom)
There were
visits to this blog since 20.08.2007.
Blog Archive
-
►
2011
(1)
- ► December 2011 (1)
-
▼
2007
(9)
- ► September 2007 (1)
-
▼
August 2007
(8)
- Ajax not only for Web: Using XmlHTTPRequest in the...
- JScript arrays and COM objects, part 3
- JScript arrays and COM objects, part 2
- JScript arrays and COM objects, part 1
- Controlling Winamp programmatically using Delphi
- My website rebuilt
- New version of MultiDesktop & Google Desktop hybri...
- Hello and Welcome to my blog!
2 comments:
Great! You cured my headache by pointing out that the elements types in safearray should be VARIANT. Thanks
Thank you!
I've solved my problem!
Post a Comment