通过引用传递对象指针 [英] Passing object pointer by reference
问题描述
嗨
我有一个在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.
===========================================================
TheMarshal::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.
TheIntPtr.ToPointer()
returns a good oldvoid *
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屋!