在我写的本地dll包装中,我刚刚用SafeHandles替换了IntPtr的所有用法(用于编组句柄)。我的印象是,正确书写的SafeHandle类型可以通过这种方式与IntPtr互换。将非SafeGuard从非托管状态管理到托管状态
但是,我Marshal.GetFunctionPointerForDelegate呼叫现在抛出一个异常:
Cannot marshal 'parameter #n': SafeHandles cannot be marshaled from unmanaged to managed.
回调包含在参数列表中的手柄,所以委托含有(a SafeHandle的在它的地方,而不是一个IntPtr作为之前)。所以我可以不这样做?如果是这样,我有什么选择使用SafeHandles,因为我需要编组回调?
这里的原生DLL头的一个编辑的例子:
struct aType aType;
typedef void (*CallBackType)(aType*, int);
aType* create(); // Must be released
void release(aType* instance);
int doSomething(aType* instance, int argumnet);
void setCallback(CallbackType func);
,是造成我的麻烦是回调位。 C#的侧面看上去像这样:
delegate void CallBackType(IntPtr instance, int argument);
然后:
var funcPtr = Marshal.GetFunctionPointerForDelegate(del = new CallbackType(somefunc)):
NativeFunction.setCallback(funcPtr)
这工作得很好,而且总是做了。不过,我想从IntPtr转移到处理安全句柄,并且读取它是一个替代品的下降。然而,在上面的C#代码的SafeHandle子类取代的IntPtr造成报告的异常:
delegate void CallBackType(MySafeHandle instance, int argument);
不是SafeHandle的.NET方面(而不是本地)的概念?你的interop声明是什么样的? –
SafeHandle确实是一个.NET Side概念(与IntPtr一样)。将更多的细节添加到我原来的问题。 –
SafeHandle是一个抽象类。 pinvoke编组没有任何方法可以从声明中选择正确的派生类类型,它只有一个IntPtr。 –