问题描述
void ReleaseHandle(void* handle){
Machine.motor motor =static_cast<Machine.IMotor*> (handle)
if (motor == 0) throw;
delete motor;
handle = nullptr;
}
到目前为止,我可以使用 uint 作为数据类型在 Managed 中使用 PInvoke 将变量传递给 Releasehandle,问题是传递的变量的值不会改变。这个方法不是整个包,但我认为这足以说明我想要做什么。我需要更改值,因为如果托管端的指针没有更改,并且我决定再次从托管调用 releaseHandle,它将抛出堆栈跟踪,因为调用了 releaseHandle 并且未找到(释放)机器。
我尝试了很多将数据类型作为 ref 从托管传递的方法,包括但不限于:
我希望当我像管理一样调用 ReleaseHandle
uint managedHandle = 123213124;
ReleaseHandle(managedHandle);
Console.WriteLine(managedHandle); // this outputs to 0
感谢您的帮助。
解决方法
您的基本问题是,您打算更改按值传递的变量。
话虽如此,正如 Matthew Watson 在对您的问题的评论中指出的那样,您必须调整您在 DLL 中调用的方法的接口,以获取指向您想要的指针位置的指针修改。
在您的示例中,您需要将指向 managedHandle
的指针传递给 ReleaseHandle
。
因此,您的 DLL 中的代码应如下所示:
void ReleaseHandle(void** handle) {
*handle = nullptr; /* Note that here we dereference one level
to modify the content of the location
pointed at */
}
另一方面,在您的 C# 程序中,您应该使用以下内容导入函数:
[DllImport("YourLibrary.dll")]
static extern void ReleaseHandle(ref IntPtr handle);
并使用 ref
关键字调用它:
IntPtr value = IntPtr.Add(IntPtr.Zero,123456789);
ReleaseHandle(ref managedHandle);
Console.WriteLine(managedHandle); // this outputs to 0