【问题标题】:How to properly dispose of pinvoke/unmanaged code如何正确处理 pinvoke/非托管代码
【发布时间】:2015-05-01 18:07:59
【问题描述】:

我有需要调用 c dll 的代码,在我看来,这段代码应该实现 idisposible,因为它涉及非托管代码。我可能是错的,如果这不是真的,请纠正我。

阅读这些东西,我似乎应该使用安全手柄。伟大的。除了我的 dll 不返回任何句柄或 intptr。那么现在怎么办?

签名大多如下:

HRESULT _XYZFN XYZNewTrip (Trip *pTripID); 

参数值:

pTripID:指向一个 4 字节整数的指针,新的 Trip 句柄将在该整数中 放置

我可以在里面装上保险柜把手吗?这似乎是article 的难题。

【问题讨论】:

    标签: c# c pinvoke safehandle


    【解决方案1】:

    如果它不返回句柄,那么显然你不能释放任何东西,所以IDisposable 模式将毫无用处。

    唯一的:

    pTripID: pointer to a 4 byte integer in which the new Trip handle will be placed
    

    这些pTripID 你将如何释放它们?大概有一个

    void XYZFreeTrip(Trip tripID);
    

    在这种情况下,您必须收集所有获得的tripID 并将它们释放到IDisposable

    现在如果Trip 是句柄,那么您有两种选择:

    • 您的代码仅适用于 x86(例如,因为 PInvoke DLL 仅适用于 x86):sizeof(int) == sizeof(int*) == IntPtr.Size,因此您可以使用 包装非托管资源 - 为指针定义级别 0 类型(中间案例)

    • 您的代码是 x86 和 x64:包装非托管资源 - 为非指针数据定义 0 级类型(硬情况) :-((而不是 ushort 你有int)

    【讨论】:

    • tripID 只是整数。至少我目前是如何得到它们的。但是有一个 DeleteTrip 方法。还有一个 InitSrv 方法和 CleanupSrv 方法,应该在每次应用启动时调用一次。行程方法将被多次调用。我想我不明白为什么 idisposible 没有用。它需要以某种方式清理。
    • @nportelli 然后你需要处理的是Trip。它们必须封装在SafeHandle 中并使用DeleteTrip 处理
    • 嗯,好吧,我觉得开始有点意思了。即使现在我们将tripID作为一个int?而且它返回一个负数与错误无关吗?是的,我假设我有困难的情况,我试图用 in 而不是 ushort 来实现它。但不是在tripID周围。但根据 hresult 它返回初始 InitSrv 方法。围绕 tripID 更改它是有意义的想法......尽管这对我来说是有意义的。
    • @nportelli 即使您将它们视为int,也有一个表为每个int 值关联一个指向某个资源的指针。当您收到错误时,我不知道您必须如何处理Trip。 “理智”的实现不会在错误时返回“有效”对象(通常将其归零),但您必须检查。
    猜你喜欢
    • 2014-07-09
    • 1970-01-01
    • 2012-03-04
    • 2010-09-18
    • 1970-01-01
    • 2011-05-21
    • 2010-12-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多