Автоматически создавать оболочки C # из заголовков c?

Есть ли способ автоматически создавать оболочки p / invoke для .net из заголовка c?

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

Я пробовал SWIG, но он создал полные классы, где было бы достаточно простых структур. Другая проблема с SWIG заключается в том, что для него требуется дополнительный код взаимодействия на стороне c.

Я бы предпочел, чтобы выход работал и в моно, но это не обязательно.

Еще одна вещь, с которой я мог бы работать, - это программа, которая анализирует заголовок c и создает вывод в удобном промежуточном формате, таком как xml, из которого я могу сам создать оболочку C #.

Изменить:
PInvoke Interop Assistant - это то, что мне нужно.
Однако с ним есть некоторые небольшие проблемы:
* Он переводит "unsigned char *" в строку, где я Я бы предпочел IntPtr
* Предполагается, что size_t = int = long = 32bit. В настоящее время это верно для меня, но может не для всех платформ.
Есть ли чистый способ исправить это? В противном случае я немного воспользуюсь поиском и заменой в коде c перед его преобразованием.


person Winner    schedule 25.03.2010    source источник


Ответы (2)


Вам больше подойдет PInvoke Interop Assistant, он был специально разработан для работать с кодом C.

Просто помните, что ни один инструмент не дает вам 100% гарантированного решения, объявления C way слишком неоднозначны, чтобы гарантировать полностью безотказный результат. Проблемы, вызванные указателями, вездесущими в коде C. Невозможно сказать, что указатель используется для чтения или записи памяти. Или оба. Или кто отвечает за освобождение памяти, на которую указывают.

Это серьезная проблема и для статических анализаторов кода: они не могут нормально работать, если не знают, как используется указатель. Они могут сделать это только исходя из использования, но это проблема курицы и яйца, использование может быть неправильным. Microsoft решила проблему в своих заголовках с помощью аннотаций SAL и дополнительной разметки. это нейтрально для компилятора, но может быть проанализировано анализатором кода. В них явно указывается предполагаемое использование указателя.

Также используется Pinvoke Interop Assistant, поэтому он может лучше справляться с объявлениями winapi. Но это, конечно, работает только с заголовками Microsoft, эти аннотации SAL обычно отсутствуют в коде, написанном занятым программистом на C.

person Hans Passant    schedule 25.03.2010
comment
Я согласен с Interop Assistant. Однако имейте в виду, что в графическом интерфейсе есть раздражающая ошибка (ограниченная длина, раздражающая, если вы хотите перевести много файлов заголовков), а сгенерированный код C # для битовых полей не только действительно уродлив, но и неверен (т.е. вы должны < / i> проверить код битового поля вручную). Я обнаружил, что для чего-либо, кроме битовых полей, он работает нормально, хотя первое, что я делаю с кодом, - это удаляю длинные пространства имен (System.Runtime.InteropServices для каждого атрибута). - person OregonGhost; 25.03.2010
comment
С этим есть небольшие проблемы. Он переводит unsigned char * в строку, где я бы предпочел IntPtr, и предполагает, что int = long = 32bit. Есть ли чистый способ исправить это? В противном случае я немного воспользуюсь поиском и заменой в коде c перед его преобразованием. - person Winner; 25.03.2010
comment
Это та двусмысленность, о которой я вас предупреждал. Нет чистого способа, исправлять созданное объявление P / Invoke - это нормально. Кстати: int и long в большинстве кодов C / C ++ 32 бита. - person Hans Passant; 25.03.2010
comment
Очевидно, заголовки c неоднозначны. Вот почему я надеялся, что смогу создать файл, влияющий на преобразование кода и переопределяющий некоторые сопоставления типов. Но поиска и замены должно хватить для моей текущей проблемы. Одна интересная особенность Interop Assistant заключается в том, что он может создавать XML-файл, который может быть полезен в сложных случаях. - person Winner; 25.03.2010

Если я правильно понимаю ваш вопрос, вы в основном спрашиваете, есть ли способ сделать то, что делает SWIG.

Конечно, вы хотите сделать это немного по-другому, поэтому один из вариантов - взять код SWIG и изменить его так, чтобы он работал так, как вы хотите.

person John Fisher    schedule 25.03.2010