Returning a Collection object from .NET to VB6 (using COM Interop)

S

Scott M. Lyon

As I mentioned in my other post, I'm attempting to, using COM Interop so I
can update existing VB6 code to (for several specific functions) return a
Hashtable from a .NET library.


I've had very little luck processing the Hashtable itself in VB6 (I can add
a reference to the project so it knows what a Hashtable is, but I'm not
having much luck looping through all objects in the Hashtable), so I decided
to try a different idea.


I thought I'd write a quick function (in .NET) that would convert the
Hashtable to a more-vb6-friendly Collection object instead. That way VB6
could call the function to return the Hashtable, then use that return value
to call my new ConvertToCollection function, returning a Collection.


Problem: for some reason, every time I call a .NET function that returns a
Collection object from VB, if I try to put the return value in a (VB6)
Collection, I geta "type mismatch" error.


I can store the (.NET) Collection in a (VB6) Variant, but when I try to
assign THAT value to my (VB6) Collection, I get the "type mismatch" again...


It's making me wonder if the .NET Collection object is incompatible with the
VB6 Collection object.


Can anyone confirm this? Or least offer suggestions how I can get past this,
so I can work with the data from my Hashtable/Collection from VB6?


Thanks!
-Scott
 
S

Scott M. Lyon

Let me give you a specific example of what I'm seeing:


In my .NET library I added the following function:

Public Function ReturnCollection() As Collection
Dim aColl As New Collection
aColl.Add("test 1", "1")
aColl.Add("test 2", "2")
aColl.Add("test 3", "3")
aColl.Add("test 4", "4")

Return aColl

End Function


In VB6 (using COM Interop), I have a reference to that .NET library, let's
call it MyLibrary.

I'm trying to call it with this code:

Dim oMyLibrary As New MyLibrary
Dim oCollection As Collection

Set oCollection = oMyLibrary.ReturnCollection


And it fails on that Set statement with the "Type Mismatch".


So I changed the VB6 code to the following:

Dim oMyLibrary As New MyLibrary
Dim oObject As Object
Dim oCollection As Collection

Set oObject oMyLibrary.ReturnCollection
Set oCollection = oObject

And this one fails on the last Set statement. But when I add a watch to
oObject and oCollection, it tells me that oCollection is of type Collection
(as expected), and that oObject is of type Object/Collection (which also
seems reasonable).


So why is it failing with a "type mismatch"? Won't it let me assign an
Object/Collection to a Collection?

Thanks!

-Scott
 
L

Larry Lard

Scott M. Lyon wrote:
[snip]
It's making me wonder if the .NET Collection object is incompatible with the
VB6 Collection object.

Your wonderings are correct. They are completely different types of
thing! Do not let the name fool you! (as evidence they are completely
different types of thing, I offer their starkly different public
interfaces).
Can anyone confirm this? Or least offer suggestions how I can get past this,
so I can work with the data from my Hashtable/Collection from VB6?

COM Interop is a messy business at best. I am no expert, but my advice
would be to stick to native COM data types.

I will look for your other posts to see if there is anything more
specific I can offer
 
S

Scott M. Lyon

Your wonderings are correct. They are completely different types of
thing! Do not let the name fool you! (as evidence they are completely
different types of thing, I offer their starkly different public
interfaces).


Ahhh, I was afraid of that... In that case, guess I need to find another
solution to my problem.


In a nutshell, I have various .NET public functions that return Hashtable
objects (containing custom defined objects). I need to find a way that VB6
can work with this data.

My original thought with Collections is that I could add another function to
..NET that would convert the Hashtable to a Collection that VB6 could deal
with, and then the VB6 code would have to make the initial call (to get the
Hashtable), then a second call to convert that hashtable to a collection (or
whatever).


Any ideas how I'd be able to pull this off, without significant coding on
the VB6 side every time it needs to work with a Hashtable?


(You see, the problem is that while I support the .NET side of this, the VB6
side is a few other developers, and I really don't want to complicate
matters too terribly much on their end, for fear it would introduce too much
possibility for error)


Thanks!
-Scott
 
L

Larry Lard

Scott said:
Ahhh, I was afraid of that... In that case, guess I need to find another
solution to my problem.


In a nutshell, I have various .NET public functions that return Hashtable
objects (containing custom defined objects). I need to find a way that VB6
can work with this data.

My original thought with Collections is that I could add another function to
.NET that would convert the Hashtable to a Collection that VB6 could deal
with, and then the VB6 code would have to make the initial call (to get the
Hashtable), then a second call to convert that hashtable to a collection (or
whatever).


Any ideas how I'd be able to pull this off, without significant coding on
the VB6 side every time it needs to work with a Hashtable?

I've had a little google around, and it looks like it might be possible
(with some unpretty trickery) to get VB6-enumerable objects out of .NET
- however even if we managed this, I fear we would still have a problem
with this bit:
objects (containing custom defined objects). I need to find a way that VB6
can work with this data.

In that even if we manage to enumerate through a collection and get
stuff out of a hashtable, we will still have a .net object. Now, if we
are going to write code to present these underlying objects in a COM
friendly way, we might as well go as far as creating a complete
"translation layer" that keeps all out actual Interop calls at the
basic data type level.

What I mean is this: instead of trying to build this:

_____
vb6 side .NET side

hashtable(complex object)
<-- some magic ----------

enumerable collection

For Each complex object

<------- ? invoke methods on the complex object
to get the actual info we want
in a COM-friendly format -------->

COM-friendly basic data types (strings, ints etc)

do actual work
____

it might actual be easier to build this:

vb6 side .NET side

--- tell me about the hashtable ---->

<------- return a simple array of the keys,
or the IDs, or some other basic data type
that identifies each hashtable entry -------

--- ask *specific* *simple* questions about the complex objects
---->

<-------- return basic COM data types that answer the questions
-------

_____________

To try and restate it again (because I'm not sure how clear this is):

Suppose we had on the .NET side a hashtable of string -> string(), eg

Key: "Fruit" Value: { "Apple", "Orange", "Banana" }
Key "Animal" Value: { "Horse", "Dog", "Cat" }

Instead of trying to pass that <en masse> to vb6, instead just have
methods that return:

- the number of top-level entries
- the key of the nth entry
- the number of entries in the list of the nth entry
- the mth entry in the list of the nth entry

which all return basic data types but are still sufficient to get all
the data (eg we call the first, get 2, call the second for 1 and 2, get
Fruit and Animal, call the third for 1, get 3, call the fourth for 1,1;
1,2; 1,3; 1,4 and so on)
(You see, the problem is that while I support the .NET side of this, the VB6
side is a few other developers, and I really don't want to complicate
matters too terribly much on their end, for fear it would introduce too much
possibility for error)

So at the moment they are already operating on these complex .NET
objects, or what?
 
S

Scott M. Lyon

So at the moment they are already operating on these complex .NET
objects, or what?

No, actually at the moment they're calling old VB6 components to do
essentially the same thing as the new .NET library does.

But we're trying very hard to get away from supporting two different
platforms for exactly the same processing.
 
L

Larry Lard

Scott said:
No, actually at the moment they're calling old VB6 components to do
essentially the same thing as the new .NET library does.

But we're trying very hard to get away from supporting two different
platforms for exactly the same processing.

Well I would say then make a .net layer that just returns the
simple-data-type answers. Without learning the details I can't offer
much more.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top