C ++ int & long marshalling в C # - PullRequest
       0

C ++ int & long marshalling в C #

3 голосов
/ 27 декабря 2010

В настоящее время я портирую проприетарную dll (API) на C #, и у меня возникают некоторые проблемы при сортировке некоторых используемых типов данных.

Например, файл заголовка API определяет следующие типы:

typedef unsigned int  tINT;  /* natural unsigned */
typedef signed int    tINTs; /* natural signed */
typedef unsigned int  tLONG; /* 32 bit unsigned */
typedef unsigned long tPTR;  /* 32/64-bit pointer */

Тогда у меня, например, есть следующее определение функции:

tINTs SomeApiFunction ( const tPTR hdl, tINT param );

Обычно я пишу int напрямую с помощью C # int (Int32) или неподписанной версии. API tLONG и tINT одинаковы (по крайней мере, для API). Но я не уверен с tPTR. Теперь я сделал это uint в C #, потому что это 32-битное int, но я не уверен, как long будет вести себя на 64-битной машине.

Что мне нужно сделать, чтобы убедиться, что API будет работать правильно как на 32-битных, так и на 64-битных машинах?

Вот что бы я сделал сейчас:

[DllImport( "api.dll" )]
public static extern int SomeApiFunction ( uint hdl, uint param );

К сожалению, API не очень хорошо документирован, поэтому я не уверен, каково было намерение со всеми этими (перекрывающимися) typedefs. Помимо комментариев заголовка, которые я включил выше, нет никакой информации о фактических типах.

Ответы [ 4 ]

3 голосов
/ 27 декабря 2010

Это деталь реализации компилятора C / C ++. Вы должны пойти по комментарию и объявить его IntPtr. Если код скомпилирован компилятором MSVC, он не будет работать в 64-битном режиме, он будет долго использовать 32-битный. Недостаточно для хранения указателя.

3 голосов
/ 27 декабря 2010

Попробуйте маршалировать это как IntPtr.IntPtr - это 4 байта в 32-битной системе и 8 байтов в 64-битной системе в .Net.

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

Вот хороший список соответствия типов.

Для типов указателей обычно IntPtr в C #.

1 голос
/ 27 декабря 2010

Если я правильно помню, int uint и другие примитивные типы являются правильным типом для базового API Windows.

Однако для указателей лучше использовать IntPtr на стороне C # и void* на стороне C / C ++.

...