Tracking References

The last couple of blog entries I made were on native C++ references and I thought maybe it’s a good time to talk about tracking references in C++/CLI. The punctuator used to specify a tracking reference is % (similar to & for a native reference). See the code snippet below :-

void ChangeString(String^ str)
{
    str = "String has been changed";
}

void _tmain()
{
    String^ str = "Hello World";
    ChangeString(str);
    Console::WriteLine(str);
}

The output will show that the function didn’t really change the string the way we intended it to. Now modify the ChangeString function as follows :-

void ChangeString(String^% str)
{
    str = "String has been changed";
}

Okay, now it works as expected. For C# folks, this is similar to what happens when you use the ref keyword for function arguments.

Advertisements

7 thoughts on “Tracking References

  1. I don’t have Whidbey here to test with, but I don’t see why the assignment to str in ChangeString() isn’t reflected in main. When you write str="foo" you’re changing the state of the underlying String object, no?

  2. Hey Mike

    The .NET String object is immutable. So if you change a String’s underlying string, what happens is that a new String object is allocated and assigned to the handle variable. In the first case, because the handle variable is only a copy of the handle variable in main, the handle variable in main is not affected. But in the second case the handle variable is the same one as in main because of the % punctuator.

  3. ah, ok, it’s a syntactic shortcut that was confusing me. The line in ChangeString() really means:

    str = gcnew String("String has been changed");

    When it’s written without the shortcut, it’s clearer. 🙂

  4. Hi,

    I am trying to use a function in a .dll that I have added as a COM reference in VC++, VS2008. In the Object Viewer, it appears as: public virtual void QueryAvailableProperties(string ItemID, out int Count, out int[ ] PropertyIDs, out string[ ] Descriptions, out short[ ] DataTypes). When I hover the mouse above code as I am typing, the tooltip displays: QueryAvailableProperties(String ^ItemID, int % Count, array ^% PropertyIDs, array ^% Descriptions, array ^% DataTypes). The later indicates passing array tracking references but I have not being able produce a solution. The variable Count returns a correct value but an exception Message = “SafeArray cannot be marshaled to this array type because it has either nonzero lower bounds or more than one dimension.” is thrown. An equivalent VC#, VS2008 project returns correct values. Any help would be greatly appreciated.

    Regards

    Ravith

  5. When I referenced the .dll in VC#, it generated an Interop.xxxxxx.dll and adding that file as a reference in my VC++ project seems to have solved the problem. The function allows me to pass Array^ types instead of the cli:array^ type required originally.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s