从非托管C库访问C#方法是否安全?

时间:2015-10-02 03:34:46

标签: c# c++ pointers delegates shared-libraries

我正在从C访问C#的方法。下面是C#中的一些代码片段。

select distinct cats.id, cats.name, cats.age 
from Cat as cats
        inner join cats.Kitten on Kitten.catid = Cat.id
        left outer join Owner on Kitten.ownerid = Owner.id
        left outer join Vet_Doctor on Kitten.doctorid = Vet_Doctor.id
 where Kitten.gender = 'male';


select Kitten.id, Kitten.name, Owner.name, Vet_Doctor.name 
from Cat
        inner join Kitten on Kitten.catid = Cat.id
        left outer join Owner on Kitten.ownerid = Owner.id
        left outer join Vet_Doctor on Kitten.doctorid = Vet_Doctor.id
 where Cat.id = 1;

setFuncPtr()是C库的一个函数,用于设置C#方法的指针。在这段代码之后我可以随时调用C库中的C#方法而没有任何问题,但我不确定这是否正常。

当在C#中使用存储在堆中的变量的指针时,由于GC,必须使用关键字“fixed”。因为内存的堆栈部分包含方法,所以我编写上面的代码是有意义的。但是因为我还没有看到人们这样写,我希望听到你的意见。

这是一个非常简单的问题,但对我来说却是一个非常重要的问题。 我不想写不安全的代码。

1 个答案:

答案 0 :(得分:2)

您需要确保委托实例不是垃圾回收。

为此,您只需将其存储在一个字段中,并确保只要非托管代码挂在指针上,该字段就会生根。

这是必要的,因为委托不仅存储指向.Net方法的指针,还存储状态(第一个参数;通常为this)。要为此创建一个函数指针,运行时必须创建一个引用此对象的thunk,以便非托管代码可以从函数指针中获取。这受委托实例的生命周期限制。

有关委托和函数指针之间差异的更多信息,请参阅my blog