Marshal 2 IntPtr 在同一个函数中?
Posted
技术标签:
【中文标题】Marshal 2 IntPtr 在同一个函数中?【英文标题】:Marshal 2 IntPtr's in the same function? 【发布时间】:2014-01-17 13:45:38 【问题描述】:我想知道如何用 C# 语言编组我在 C++ 中创建的 2 个类。 (一个教程链接会很完美,我试着自己用谷歌搜索,但我的英语知识不是那么先进,要搜索正确的东西。我是从 C++ 编组到 C# 的新手)
嗯,基本上我所拥有的是这样的:
C++
EXPORT_API CarClass* DLL_AddCar();
EXPORT_API CarWheel* DLL_AddWheel();
EXPORT_API void DLL_GiveWheelToCar(CarClass* car,CarWheel* wheel);
C#
public class Car
#region Members
private IntPtr nativeCarObject;
#endregion Members
public Car()
this.nativeCarObject = Sim.DLL_AddCar();
// ---> this part is not working
//#region Wrapper methods
//public void GiveWheel(Wheel myWheel)Sim.DLL_GiveWheelToCar(this.nativeCarObject,myWheel);
//#endregion Wrapper methods
public class Wheel
#region Members
private IntPtr nativeCarObject;
#endregion Members
public Wheel()
this.nativeCarObject = Sim.DLL_AddWheel();
internal class Sim
public const string pluginName = "MyDLL";
#region PInvokes
[DllImport(pluginName)] public static extern IntPtr DLL_AddCar();
[DllImport(pluginName)] public static extern IntPtr DLL_AddWheel();
[DllImport(pluginName)] public static extern void DLL_GiveWheelToCar(IntPtr car,IntPtr wheel);
#endregion PInvokes
现在我的问题是我将在哪里使用 "DLL_GiveWheelToCar" ? 我尝试的方法被注释掉了,因为它不起作用,是逻辑错误还是我应该改变我编组的方式?
感谢您的建议。
【问题讨论】:
【参考方案1】:public void GiveWheel(Wheel myWheel)
Sim.DLL_GiveWheelToCar(this.nativeCarObject, myWheel);
在这里,您将myWheel
类型为Wheel
传递给需要IntPtr
的函数。您需要传递当前(错误)命名为 nativeCarObject
的 Wheel
类的私有字段。
其他要点:
-
正如我上面所暗示的,
Wheel
的成员 nativeCarObject
应重命名为 nativeWheelObject
。
DLL 看起来使用cdecl
调用约定。您应该在 p/invoke 声明中指定这一点。
您的代码似乎泄露了 DLL 提供的对象。我怀疑您需要提供一些整理帮手。
代码可能如下所示:
public class Car
public readonly IntPtr nativeCarObject = Sim.DLL_AddCar();
public void GiveWheel(Wheel myWheel)
Sim.DLL_GiveWheelToCar(this.nativeCarObject, myWheel.nativeWheelObject);
public class Wheel
public readonly IntPtr nativeWheelObject = Sim.DLL_AddWheel();
internal class Sim
public const string pluginName = "MyDLL";
[DllImport(pluginName, CallingConvention=CallingConvention.Cdecl)]
public static extern IntPtr DLL_AddCar();
[DllImport(pluginName, CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr DLL_AddWheel();
[DllImport(pluginName, CallingConvention = CallingConvention.Cdecl)]
public static extern void DLL_GiveWheelToCar(IntPtr car, IntPtr wheel);
此代码仍在泄漏这些对象。我会让你解决这个问题。
【讨论】:
谢谢!我做了改变。关于对象本身,我创建了一个 GetObject 方法,该方法返回它的 IntPtr。是否有可能以某种方式从 IntPtr 派生? 我认为从IntPtr
派生没有意义。以上是关于Marshal 2 IntPtr 在同一个函数中?的主要内容,如果未能解决你的问题,请参考以下文章