views:

313

answers:

1

I have a C# .Net console application which calls a C++ .Net class library. However, when the following application is executed, the list becomes empty!!!

If I remove the line as indicated in the comment next to it, the code works. I don't understand the reason for this.

If I want to reallocate the memory for list in the C++ class library as what I am trying to do below, what is the correct way to go about doing it?

C#2005 Console Application

class Caller
{
    static void Main(string[] args)
    {
        Callee callee = new Callee();
        List<String> s = new List<String>();
        callee.DoSomething(s);

        Console.WriteLine(s.Count); // Prints out 0
    }
}

C++2005 Class Library

public ref class Callee
{
    public:
    void DoSomething(List<String^>^ list);
};

void Callee::DoSomething(List<String^>^ list)
{
    list = gcnew List<String^>(); // Remove this line and it works
    list->Add(gcnew String("Test String 1"));
    list->Add(gcnew String("Test String 2"));
}
A: 

You want the equivalent of this in C++/CLI (C# code follows)

class Caller
{
    static void Main(string[] args)
    {
        Callee callee = new Callee();
        List<String> s = new List<String>();
        callee.DoSomething(ref s);

        Console.WriteLine(s.Count); // Prints out 0
    }
}

public class Callee 
{
    void DoSomething(ref List<string> list)
    {
        list = new List<string>(); 
        list.Add("Test String 1");
        list.Add("Test String 2");
    }
}

Notice that 'list' there is passed by reference so when you allocate a new object it will change the original variable that was being passed into the function.

The equivalent C++/CLI syntax is as follows:

public ref class Callee
{
    public:
    void DoSomething(List<String^>^% list);
};

void Callee::DoSomething(List<String^>^% list)
{
    list = gcnew List<String^>(); 
    list->Add(gcnew String("Test String 1"));
    list->Add(gcnew String("Test String 2"));
}

The addition of the "%" to the type there will make list get passed in as a tracking reference.

More information about tracking references can be found at http://en.wikipedia.org/wiki/C%2B%2B/CLI#Tracking%5Freferences

Smirnov
@Smirnov: It works now. Many thanks! :)
KK
@Smirnov: C# can also make use of the "out" keyword. Is there an equivalent in C++/CLI?
KK
If you set the [Out] attribute on it, it will be identical to the "out" keyword, e.g.void Callee::DoSomething([Out] List<String^>^% list)
Smirnov
@Smirnov: Thanks! :)
KK