Допустимо ли использовать небезопасную структуру * в качестве непрозрачного типа вместо IntPtr в .NET Platform Invoke? - PullRequest
3 голосов
/ 21 декабря 2010

.NET Platform Invoke поддерживает объявление типов указателей как IntPtr.Например следующееделать.

Я использовал шаблон, в котором я объявляю небезопасную структуру типом непрозрачного указателя.Я могу сохранить этот тип указателя в управляемом объекте, и компилятор может проверить его для меня.Например:

class Foo {
   unsafe struct FOO {};  // opaque type
   unsafe FOO *my_foo;

   class if {
     [DllImport("mydll")]
     extern static unsafe FOO* get_foo();

     [DllImport("mydll")]
     extern static unsafe void do_something_foo(FOO *foo);
   }

   public unsafe Foo() {
     this.my_foo = if.get_foo();     
   }
   public unsafe do_something_foo() {
     if.do_something_foo(this.my_foo);
   }

ПРИМЕЧАНИЕ. Я не пытаюсь упорядочить структуру.DLL предоставляет непрозрачный указатель, к которому я не должен прикасаться, мне просто нужно предоставить его для будущих вызовов DLL.

Я знаю, что опубликованный способ сделать это - IntPtr, но я нене нравится использовать нетипизированный указатель.Когда есть несколько типов указателей, перемещающихся между управляемым и собственным кодом, использование IntPtrs очень опасно.Использование моих непрозрачных типов структурных указателей для проверки типов является хорошей находкой.

Я не сталкивался с какими-либо проблемами при использовании этой техники на практике.Однако я также не видел примеров того, чтобы кто-нибудь использовал эту технику, и мне интересно, почему.Есть ли какая-либо причина, по которой приведенный выше код недопустим в глазах среды выполнения .NET?

Мой главный вопрос о том, как система .NET GC обрабатывает «небезопасное FOO * my_foo».Я надеюсь, что поскольку базовый тип является структурой, а он объявлен небезопасным, GC проигнорирует его.

Является ли этот указатель чем-то, что система GC попытается отследить, или она просто проигнорирует его?Безопасно ли использовать мою технику вместо IntPtr?

Ответы [ 2 ]

2 голосов
/ 25 декабря 2010

Похоже, что ответ «да» ... «небезопасные указатели обрабатываются как типы значений», что означает, что их безопасно использовать для хранения непрозрачных типов. В некотором смысле они работают точно так же, как IntPtr, но они идут с дополнительной проверкой типов, потому что разные типы небезопасных указателей не считаются одинаковыми, как если бы вы сделали их все IntPtr.

Для более подробной статьи, которую я написал по этой теме, ознакомьтесь ..

http://www.codeproject.com/script/Articles/ArticleVersion.aspx?waid=1210&aid=339290

0 голосов
/ 23 декабря 2010

Я бы не использовал небезопасный код и указатели. Почему бы просто не определить структуру и позволить CLR выполнить отображение:

[StructLayout(LayoutKind.Sequential)]
public struct Foo
{
    public int Field1;
    public long Field2;
}

и затем:

[DllImport("mylib")]
static extern void do_something_foo(ref Foo foo);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...