Click here to Skip to main content
Click here to Skip to main content
Go to top

Using .NET Collections from Native Code

, 29 May 2008
Rate this:
Please Sign up or sign in to vote.
A short example of how to access a managed ArrayList of Strings from Native C++/ATL

Introduction

As projects are migrated to the .NET Framework, there is often a need to integrate newly developed .NET based functionality into existing, not-yet-migrated, legacy COM applications. Ideally, the code being developed on the .NET Framework should take advantage of the rich class libraries that the framework has to offer. This can pose several problems for COM clients that want to use the managed code since COM and .NET have differing object models, memory models and runtime requirements.

Fortunately, many of the .NET Framework classes are exposed to COM clients via mscorlib.tlb. A quick look at mscorlib.tlb in OleView reveals just how much of the basic framework is COM Visible:

DotNetCollectionsFromNativeCodeDemo_OleView.GIF

There are many more classes that are visible to COM objects. In fact, every class that is marked ComVisible(true) in the API documentation can be easily accessed from COM clients.

Using the Code

This example shows how to use a System.Collections.ArrayList from native C++. The C++ client makes use of ATL.

The managed class method Library.GetBooks() returns an ArrayList. A single string was added to this list in the Library() constructor. The following snippet prints a count of the number of items in the list (in this example, there is only 1):

ILibraryPtr ptrLibrary(__uuidof(Library));

IUnknown *ptrUnkBooks = NULL;

// ManagedCSharpDemoLibrary::_ArrayList is a stub struct
// created by InteropServices.  Since everything in COM
// derives from IUnknown, it's safe to cast from an IUnknown *
ptrLibrary->GetBooks((ManagedCSharpDemoLibrary::_ArrayList **)&ptrUnkBooks);

// ICollection is defined in mscorlib.tlb.  It corresponds
// to System.Collections.ICollection

ICollection *ptrCol = NULL;
ptrUnkBooks->QueryInterface(__uuidof(ICollection), (void **)&ptrCol);

long count = -1;
ptrCol->get_Count(&count);

cout << "Number of books: " << count << endl;

The System.Collections.ICollection.Count property contains the number of items in the ArrayList. ICollection is only one of many interfaces implemented by ArrayList. Each of these interfaces is declared as a dual interface so it can be accessed by early bound clients (like this C++ client) as well as late bound clients (e.g. VBscript).

To access the individual items in the ArrayList, the IList interface is required. The IList.Item property in the managed world provides zero based indexed access to the elements of the list. This property can be accessed as follows:

IList *ptrList = NULL;
ptrCol->QueryInterface(__uuidof(IList), (void **)&ptrList);

// ArrayLists store objects.  These are marshalled as 
// VARIANTs.  Since this list is storing strings, the
// VARIANTs are of type BSTR;

VARIANT vObj;
_variant_t vtObj; // provides a convenient way to convert to _bstr_t

for (int i=0; i < count; i++)
{
    ptrList->get_Item(i, &vObj);
        
    vtObj.Attach(vObj);

    wcout << "Found book: " << ((_bstr_t)vtObj) << endl;
}

ptrCol->Release();

This example prints out each element in the list. It can be easily adapted for lists that are not strings. The VT_* VARIANT macros can be used to determine the type of VARIANT in the list.

Points of Interest

The COM C++ compiler extensions can greatly simplify COM programming in C++. Attributed programming also provides another way to easily create and consume COM types from C++ but there are still a lot of legacy projects out there using versions of VC++ that predate attributed programming.

History

  • 29th May, 2008: First version submitted

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

arnshea
Software Developer Microsoft
United States United States
I've been a professional developer since 1996 save for a few years finishing up undergrad and getting a Masters of Science in Computer Science. I've developed in C, PERL and Java on Unix and C#, C++, C, Java and too many other languages to recall on Windows. I am a Sun Certified Java Developer and a Microsoft Certified Applications Developer (.NET; Windows Forms and Web Forms).
 
If I'm not pouring through API docs, reading programmer's blogs or attaching to a remote process in a debugger then I'm probably scouring the web for interesting articles on technology, flashing the ROM in my Windows Mobile device, making my current boss happy or parked on the couch for some olympic class relaxation.
Follow on   Twitter

Comments and Discussions

 
-- There are no messages in this forum --
| Advertise | Privacy | Mobile
Web03 | 2.8.140921.1 | Last Updated 29 May 2008
Article Copyright 2008 by arnshea
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid