从非托管 C 库访问 C# 方法是否安全?
Is it safe to access a method of C# from an unmanaged C library?
我现在正在从 C 访问 C# 的方法。下面是一些 C# 代码片段。
IntPtr pFunc = Marshal.GetFunctionPointerForDelegate (
new DelegateForMyMethodInCsharp (
MyMethodInCsharp
)
);
setFuncPtr(pFunc);
setFuncPtr() 是 C 库的函数,用于设置 C# 方法的指针。在这段代码之后,我可以随时调用 C 库中的 C# 方法而不会出现任何问题,但我不确定这是否可以。
在C#中对存储在堆中的变量使用指针时,由于GC,必须使用关键字'fixed'。因为内存的堆栈部分包含方法,所以我写上面这样的代码是有意义的。但因为我还没有看到有人这样写,所以我希望听到你的意见。
这是一个非常简单的问题,但对我来说却是一个非常重要的问题。
我不想写不安全的代码。
您需要确保委托实例未被垃圾回收。
为此,您只需将其存储在一个字段中,并确保只要非托管代码挂在指针上,该字段就已成为根。
这是必要的,因为委托不仅存储指向 .Net 方法的指针,而且还存储状态(第一个参数;通常 this
)。要为此创建一个函数指针,运行时必须创建一个引用此对象的 thunk,以便非托管代码只能从一个函数指针到达那里。这受委托实例的生命周期限制。
有关委托和函数指针之间区别的详细信息,请参阅my blog。
我现在正在从 C 访问 C# 的方法。下面是一些 C# 代码片段。
IntPtr pFunc = Marshal.GetFunctionPointerForDelegate (
new DelegateForMyMethodInCsharp (
MyMethodInCsharp
)
);
setFuncPtr(pFunc);
setFuncPtr() 是 C 库的函数,用于设置 C# 方法的指针。在这段代码之后,我可以随时调用 C 库中的 C# 方法而不会出现任何问题,但我不确定这是否可以。
在C#中对存储在堆中的变量使用指针时,由于GC,必须使用关键字'fixed'。因为内存的堆栈部分包含方法,所以我写上面这样的代码是有意义的。但因为我还没有看到有人这样写,所以我希望听到你的意见。
这是一个非常简单的问题,但对我来说却是一个非常重要的问题。 我不想写不安全的代码。
您需要确保委托实例未被垃圾回收。
为此,您只需将其存储在一个字段中,并确保只要非托管代码挂在指针上,该字段就已成为根。
这是必要的,因为委托不仅存储指向 .Net 方法的指针,而且还存储状态(第一个参数;通常 this
)。要为此创建一个函数指针,运行时必须创建一个引用此对象的 thunk,以便非托管代码只能从一个函数指针到达那里。这受委托实例的生命周期限制。
有关委托和函数指针之间区别的详细信息,请参阅my blog。