通过引用传递对象指针 [英] Passing object pointer by reference

查看:106
本文介绍了通过引用传递对象指针的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


我有一个在c ++/cli环境中使用的非托管c ++类库dll.

一切都很好,直到我开始通过引用传递对象指针,此时我得到:
在...中发生了类型为"System.AccessViolationException"的未处理的异常.

...附加信息:尝试读取或写入受保护的内存. ...
错误.


这是我要实现的目标的非常基本的示例:

在c ++/cli方面,我有这个:

...

NativeWorkerObject  *nativeWorkerObj = new NativeWorkerObject();
NativeResultsObject *nativeResultsObj;

nativeWorkerObj->DoSomeWork( &nativeResultsObj ); 

// display the results...



在本机c ++ dll中是这样的:

bool NativeWorkerObject::DoSomeWork( NativeResultsObject **nativeResultsObj )
{
   // carry out some processing and if there are no issues create the
   // results to be returned

    *nativeResultsObj = new NativeResultsObject()

   // populate results

    return( true );
}




错误发生在您尝试访问本机dll中的* nativeResultsObj时.

在完全本机的应用程序中,这一切都可以正常工作,我只能在托管环境(VS2010 .NET4)中遇到问题.


任何人都可以帮忙,我认为这与pin_ptr有关,但我无法使其发挥作用


在此先感谢
Simon

解决方案

再次感谢Richard让我改变了看法:-D

这是其他人的解决方案:

在c ++/cli方面:

...
NativeWorkerObject  *nativeWorkerObj = new NativeWorkerObject();

IntPtr managedResultsPointer = Marshal::AllocHGlobal( sizeof( NativeResultsObject * ) );

NativeResultsObject *nativeResultsPointer = ( NativeResultsObject * )managedResultsPointer.ToPointer();


nativeWorkerObj->DoSomeWork( &nativeResultsObj ); 

// display the results...

// clean up resources
Marshal::FreeHGlobal( managedResultsPointer );
delete nativeWorkerObj;




本机端无需更改.

================================================== =========


Marshal::AllocHGlobal()从锁定的非托管内存中分配内存,即垃圾收集器无法触摸它.这为您的本机指针提供了安全的内存.

IntPtr.ToPointer()返回一个很好的旧版void *,允许您根据需要相应地投射指针.

不要忘了释放使用后使用的所有资源:)


您不能在托管代码和非托管代码之间直接执行此操作,因为内存模型不匹配.您需要按照此处所述使用固定的内存="http://msdn.microsoft.com/zh-cn/library/system.runtime.interopservices.gchandle.aspx" target ="_ blank" title =新窗口"> ^ ].

Hi
I have an unmanaged c++ class library dll which I''m using within a c++/cli environment.

Everything is fine until I start passing an object pointer by reference, at which point I get:
An unhandled exception of type ''System.AccessViolationException'' occurred in...

... Additional information: Attempted to read or write protected memory. ...
error.


Here''s a very basic example of what I''m trying to achieve:

On the c++/cli side I have this:

...

NativeWorkerObject  *nativeWorkerObj = new NativeWorkerObject();
NativeResultsObject *nativeResultsObj;

nativeWorkerObj->DoSomeWork( &nativeResultsObj ); 

// display the results...



In the native c++ dll is something like this:

bool NativeWorkerObject::DoSomeWork( NativeResultsObject **nativeResultsObj )
{
   // carry out some processing and if there are no issues create the
   // results to be returned

    *nativeResultsObj = new NativeResultsObject()

   // populate results

    return( true );
}




The error occurs at the point you try to access the *nativeResultsObj within the native dll.

This all works fine in an application that is completely native, I only get the issue in a managed environment (VS2010 .NET4)


Can anyone help with this, I assume it''s something to do with pin_ptr but I have not been able to make it work


Thanks in advance
Simon

解决方案

Again thanks Richard for making me think differently :-D

Here''s the solution for anyone else:

On the c++/cli side:

...
NativeWorkerObject  *nativeWorkerObj = new NativeWorkerObject();

IntPtr managedResultsPointer = Marshal::AllocHGlobal( sizeof( NativeResultsObject * ) );

NativeResultsObject *nativeResultsPointer = ( NativeResultsObject * )managedResultsPointer.ToPointer();


nativeWorkerObj->DoSomeWork( &nativeResultsObj ); 

// display the results...

// clean up resources
Marshal::FreeHGlobal( managedResultsPointer );
delete nativeWorkerObj;




No change required on the native side.

===========================================================


The Marshal::AllocHGlobal() allocates memory from the unmanaged memory which is locked in place i.e. the garbage collector can''t touch it. This gives you the safe memory for your native pointer.

The IntPtr.ToPointer() returns a good old void * allowing you to cast the pointer accordingly for your needs.

Don''t forget to release any resources used after use :)


You cannot do this directly between managed and unmanaged code, as the memory models do not match. You will need to use pinned memory as described here[^].


这篇关于通过引用传递对象指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆