C++/CLI to C++ Tips and Tricks

orignal reference: http://blogs.msdn.com/b/jsocha/archive/2011/03/02/c-cli-to-c-tips-and-tricks.aspx

In my previous post, Writing Unit Tests in Visual Studio for Native C++, I described the approach I’m using to write unit tests for native C++ code by using C++/CLI, which is C++ code that runs inside the .NET runtime. Because of this “mixed” programming model, there are some techniques you may need to employ between C++ and C++/CLI code.

Class Instance Variables

The instance variables in C++/CLI classes are different from instance variables in naïve C++, which means you can’t mix the two blindly. For example, you can’t use native C++ classes as instance variables in your test class. The following, for example, will not compile:

public ref class MyFixture
{
MyClass m_instance;
};
You’ll get the following error message:

error C4368: cannot define 'm_instance' as a member of managed 'Tests::MyFixture': mixed types are not supported

So how do you deal with this? Instead of using a class as the type, you have to use pointers and then create/destroy the instance in the TestInitialize and TestCleanup code:

public ref class MyFixture
{
[TestInitialize]
void Initialize()
{
m_pInstance = new MyClass();
}



[TestCleanup]
void Cleanup()
{
delete m_pInstance;
}



MyClass *m_pInstance;
};


The methods marked by TestInitialize and TestCleanup run before and after each test method.

Passing a Pointer to an Instance Variable

C++/CLI instance variables have a type of interior_ptr<T> instead of the type you wrote in your code. This makes a difference if you attempt to pass either the address or a reference to this instance variable to a native C++ method or function. For example, given the class above, you might think you could write a call to one of your native methods like this:

p->SomeMethod(&m_pInstance);

Compile this and you’ll see this message:

error C2664: 'Tests::MyFixture::MyTest' : cannot convert parameter 2 from 'cli::interior_ptr<Type>' to 'MyClass **'

This error appears because .NET uses a heap—items on the heap can be moved as a result of garbage collection. In order to send a pointer to a native method/function, you need to “pin” the pointer for the duration of the call, which you can do like this:

cli::pin_ptr<MyClass *> p = &m_pInstance;
SomeMethod(static_cast<MyClass **>(p));

Once the variable p either goes out of scope, or is assigned a new value, the pointer will be free to change again.

When you’re dealing with helper methods in your test code, you can also write this type of code:

Helper(&m_pInstance);
...
void Helper(cli::interior_ptr<MyClass *> ppInstance)
{
**ppInstance =
new
MyClass();
}

posted on 2011-03-03 11:19 Enki 阅读(635) 评论(0)  编辑 收藏 引用


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


<2024年4月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

导航

统计

常用链接

留言簿

随笔档案

文章档案

搜索

最新评论

阅读排行榜

评论排行榜