GregB
3/1/2007 11:44:00 AM
We want to determine whether it's possible to develop a .NET COM-
callable wrapper (CCW) which exposes complex types that are accessible
to a VBScript client. We have found that VBS has no problem accessing
'simple' types like integer, String, Boolean. On the other hand, we
are seeking advice on the optimal approach to dealing with more
complex types, such as string arrays etc.
Marshalling Parameters
Suppose our CCW exposes a class Polygon:
public class Polygon {
public int Compare(Polygon p)
{
// Implementation here.
}
}
The ProgID for this class is Acme.Geometry.Polygon.
Here's the VBS code to initialise and compare two Polygon objects with
based on our CCW:
dim oP1, oP2
dim iResult
set oP1 = CreateObject("Acme.Geometry.Polygon")
oP1.Points = ' Initialise Points property here for 1st polygon
set oP2 = CreateObject("Acme.Geometry.Polygon")
oP2.Points = ' Initialise Points property here for 2nd polygon
iResult = oP1.Compare(oP2)
The final line leads to the following error raised by the Windows
Script Host (WSH):
438 Object doesn't support this property or method
This seems to be because oP2 loses its type information when it
crosses the COM interface. Apparently because .NET uses strong
typing, COM Interop is failing to find an overload of the Compare
method matching the 'typeless' object. At present the workaround for
this is to expose an additional, surrogate method, InteropCompare,
which accepts a weakly-typed parameter:
public int InteropCompare(Object p)
{
return Compare((Polygon) p); // explicit typecast required
}
Is there another way around this, perhaps using custom marshalling,
ie. the attribute MarshalAs()?
Marshalling Fields
Suppose our CCW exposes a class Strings:
public class Strings {
public String[] items;
}
The ProgID for this class is Acme.Strings.
Here's the VBS code to initialise a Strings object based on our CCW:
dim oStrings
set oStrings = CreateObject("Acme.Strings")
oStrings.items = Array("Mary", "had", "a", "little", "lamb")
The final line leads to this error:
5 Invalid procedure call or argument
This reference to a "procedure" or "argument" suggests that, under the
COM Interop covers, an implicit method call takes place in order to
make the array assignment.
And this attempt to read the elements in a Strings object:
dim iJoined
iJoined = ""
for I = 0 to UBound(oStrings.items) // no problem here: UBound result
is correct
iJoined = iJoined & oStrings.items(I) // fails here
next
leads to this error:
450 Wrong number of arguments or invalid property assignment
There may be other types apart from array types that fail to marshal
correctly when defined as class fields.
How can we resolve these issues for our CCW?
Thanks in advance.
GregB