Discussion:
BSTR and JScript
(too old to reply)
Petar Popara
2005-08-25 08:14:06 UTC
Permalink
I have to send from JScript to an COM object one binary value as BSTR. Is it
possible?

Example:

var b = "AAAAAAAAAAAAAAAAAAAA"; // length is allways 20

b[0] = 25;
b[1] = 30;
b[2] = 2;
b[3] = 65;
...
b[19] = 44;

myCOM.setBinaryValue(b);

Would above code work?

setBinaryValue() was already defined as BSTR inside COM object and changeing
it into SAFEARRAY would require new deployement which I would like to avoid
if possible.
Igor Tandetnik
2005-08-25 14:26:39 UTC
Permalink
Post by Petar Popara
I have to send from JScript to an COM object one binary value as
BSTR. Is it possible?
Not really. Strings in JavaScript consist of Unicode characters, they
don't handle binary data reliably.
Post by Petar Popara
var b = "AAAAAAAAAAAAAAAAAAAA"; // length is allways 20
b[0] = 25;
While this will run, it does not do anything even remotely close to what
you think it does. Strings in JavaScript are immutable - once created,
they cannot be changed. Individual characters can be obtained with
charAt() and charCodeAt() methods, but they cannot be changed.

You can try to do something like this:

var b = "\x19\x1E\x2...\x2C";
// or
var b = String.fromCharCode(25, 30, 2, ..., 44);
// or
var b = String.fromCharCode(25) + String.fromCharCode(30) + ... +
String.fromCharCode(44);
// the last variant can be used to assemble the string in a loop from
dynamicaly calculated values
Post by Petar Popara
setBinaryValue() was already defined as BSTR inside COM object and
changeing it into SAFEARRAY would require new deployement which I
would like to avoid if possible.
It won't help anyway. There is no way in JavaScript to form a SAFEARRAY
parameter. JavaScript's Array object is incompatible with SAFEARRAY.
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925
Dave Methvin
2005-08-25 15:37:54 UTC
Permalink
Post by Igor Tandetnik
var b = "\x19\x1E\x2...\x2C";
// or
var b = String.fromCharCode(25, 30, 2, ..., 44);
// or
var b = String.fromCharCode(25) + String.fromCharCode(30) + ... +
String.fromCharCode(44);
// the last variant can be used to assemble the string in a loop from
dynamicaly calculated values
If you have an array of values built elsewhere, you can also do this instead
of a loop:

var a = [68, 65, 86, 69];
var s = String.fromCharCode.apply(null, a);

Also, I seem to recall that the JScript-to-COM trip will truncate at the
first zero in some situations--maybe it was the ATL conversion macros?
Anyway, if you need imbedded zero values try a test case and make sure it
works.
Petar Popara
2005-08-26 06:40:56 UTC
Permalink
Post by Dave Methvin
Anyway, if you need imbedded zero values try a test case and make sure it
works.
Thank you guys.
Petar Popara
2005-08-29 09:43:31 UTC
Permalink
Post by Dave Methvin
var a = [68, 65, 86, 69];
var s = String.fromCharCode.apply(null, a);
I have one additional question. What if "a" contain ANSI values and not
unicode?
In the above code example String (BSTR, unicode) is fiiled with (unicode)
byte vaues. And in my example those bytes are converted back into ANSI
inside COM object (and values are then wrong):

var a = [68, 65, 86, 69]; // Unicode
var s = String.fromCharCode.apply(null, a); // Create String object from
unicode bytes
myCOM.func1(s); // Convert unicode into ANSI using WideCharToMultiByte()

I need this:

var a = [68, 65, 86, 69]; // ANSI
var a1 = convertANSItoUnicode(a); // ANSI to unicode
var s = String.fromCharCode.apply(null, a1); // Create String object
myCOM.func1(s); // Convert unicode into ANSI using WideCharToMultiByte()

Is it possible? :(
Dave Methvin
2005-08-29 18:12:56 UTC
Permalink
What if "a" contain ANSI values and not unicode?
In the above code example String (BSTR, unicode) is fiiled with (unicode)
byte vaues. And in my example those bytes are converted back into ANSI
var a = [68, 65, 86, 69]; // Unicode
var s = String.fromCharCode.apply(null, a); // Create String object from
unicode bytes
myCOM.func1(s); // Convert unicode into ANSI using WideCharToMultiByte()
var a = [68, 65, 86, 69]; // ANSI
var a1 = convertANSItoUnicode(a); // ANSI to unicode
var s = String.fromCharCode.apply(null, a1); // Create String object
myCOM.func1(s); // Convert unicode into ANSI using WideCharToMultiByte()
The String object that JScript creates is almost certainly a wide Unicode
string. If you dump out the values of the bytes in the BSTR that comes in to
myCOM.func1, what values are they?

Serge Baltic
2005-08-25 17:15:14 UTC
Permalink
Hello,

IT> It won't help anyway. There is no way in JavaScript to form a
IT> SAFEARRAY parameter. JavaScript's Array object is incompatible with
IT> SAFEARRAY.

And what about the VBArray? Is it readonly?

Anyway, the JScript array can be passed "AS IS" as IDispatch* and handled
as an ActiveX object in the COM server … If there's some existing code for
BSTRs, the parameter could be made a VARIANT which is "binary data in BSTR,
if of type VT_BSTR, and a JScript array, if VT_DISPATCH".

PS I've heard of some cases when binary data in BSTRs gets truncated during
marshalling due to the zeros within; even though it has the length stored,
sometimes it may be treated as an ASCIIZ. Are there any examples of such
situations?

(H) Serge
Dave Methvin
2005-08-25 17:37:33 UTC
Permalink
Post by Serge Baltic
PS I've heard of some cases when binary data in BSTRs gets truncated
during marshalling due to the zeros within; even though it has the length
stored, sometimes it may be treated as an ASCIIZ. Are there any examples
of such situations?
var a = [68, 65, 0, 86, 69];
var s = String.fromCharCode.apply(null, a);
WScript.Echo(s.length);
WScript.Echo(s);

Notice that the length is correct (5) but WScript.Echo stops at the first
zero. The question I can't answer at the moment is whether a custom COM
object method that accepts a BSTR will get the whole string or a truncated
version.
Serge Baltic
2005-08-26 10:03:13 UTC
Permalink
Hello,

DM> var a = [68, 65, 0, 86, 69];
DM> var s = String.fromCharCode.apply(null, a);
DM> WScript.Echo(s.length);
DM> WScript.Echo(s);
DM> Notice that the length is correct (5) but WScript.Echo stops at the
DM> first zero. The question I can't answer at the moment is whether a
DM> custom COM object method that accepts a BSTR will get the whole
DM> string or a truncated version.

This example is not quite about marshalling. I mean, if I have a COM object
with an [in] BSTR parameter, what would happen to zeros in the BSTR in different
marshalling scenarios?

(H) Serge
Petar Popara
2005-08-26 06:43:19 UTC
Permalink
Post by Igor Tandetnik
It won't help anyway. There is no way in JavaScript to form a SAFEARRAY
parameter. JavaScript's Array object is incompatible with SAFEARRAY.
As much as I remember, someone mentioned that VBArray object could be
created/used inside JScript and that it is compatible with SAFEARRAY?
Serge Baltic
2005-08-26 09:57:20 UTC
Permalink
Hello,

PP> As much as I remember, someone mentioned that VBArray object could
PP> be created/used inside JScript and that it is compatible with
PP> SAFEARRAY?

Yes it's compatible. Unfortunately, it's a constant array, ie you may work
with a SAFEARRAY given to a script (having messed with SAFEARRAY have absolutely
no idea which aspect it's "SAFE" in :), but you cannot create and author
your own array.

(H) Serg
Igor Tandetnik
2005-08-26 13:45:22 UTC
Permalink
Post by Petar Popara
Post by Igor Tandetnik
It won't help anyway. There is no way in JavaScript to form a
SAFEARRAY parameter. JavaScript's Array object is incompatible with
SAFEARRAY.
As much as I remember, someone mentioned that VBArray object could be
created/used inside JScript and that it is compatible with SAFEARRAY?
VBArray only works one way - accessing elements of an existing SAFEARRAY
or converting it to JavaScript Array. It cannot modify an existing
SAFEARRAY nor create a new one.
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925
Petar Popara
2005-08-26 14:23:14 UTC
Permalink
Thanks.
Joe Fawcett
2005-08-26 16:18:07 UTC
Permalink
You can use Scripting.Dictionary to create a SAFEARRAY. The items collection is
one once you've stocked it.
--
Joe (MVP)

https://mvp.support.microsoft.com/profile=8AA9D5F5-E1C2-44C7-BCE8-8741D22D17A5
Post by Petar Popara
Thanks.
Loading...