2013-09-03 2 views
0

Я пытаюсь использовать pinvoke для маршалирования структуры C на C#. Хотя я могу маршалировать intptr, я не могу найти синтаксис для маршалирования двойного указателя. Оба указателя int и двойной указатель используются на стороне C, чтобы выделить массив из int или double.Как маршалировать двойной указатель?

Здесь C структура:

struct xyz 
{ 
     int *np; // an int pointer works fine 
     double *foo; 
}; 

А вот с # класс:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] 
public class xyz 
{ 
    Intptr np; // works fine 
      // double *foo ?? 
    } 

Я не смог найти каких-либо инструкций о том, как MARC

+0

IntPtr - это просто указатель: до void *; поэтому вы можете попробовать маршалинг «double * foo» как «IntPtr foo»; –

+0

IntPtr не означает «указатель на целое число». MSDN: Тип IntPtr предназначен для целого числа, размер которого зависит от платформы. Он может указывать на любые данные. –

+0

Уточнение: код C выполняет все выделение/освобождает память, поэтому сторона C# блаженно не знает об этом. – PaeneInsula

ответ

0

Вы, кажется, думают, что IntPtr является указателем на int. Это не относится к делу. Значение- целое число, которое имеет ту же ширину, что и указатель. Таким образом, IntPtr имеет ширину 32 бит на x86 и 64 бит в ширину на x64. Все это ясно видно из documentation.

Ближайший эквивалентный родной тип до IntPtr is void*, нетипизированный указатель.

Так ваш класс в C# должно быть:

[StructLayout(LayoutKind.Sequential)] 
public class xyz 
{ 
    IntPtr np; 
    IntPtr foo; 
} 

Чтобы прочитать скалярное значение, np относится называть Marshal.ReadInt32. И написать это позвонить Marshal.WriteInt32. Но, скорее всего, поскольку это указатель, указатель ссылается на массив. В этом случае вы используете соответствующую перегрузку Marshal.Copy для чтения и записи.

Для указания указателя на двойное значение, если значение является скаляром, в Marshal нет способа прочитать или записать значение. Но опять же, это, несомненно, массив, в этом случае используйте Marshal.Copy для доступа к содержимому.

+0

Вы вводите в заблуждение IntPtr с массивом указателей. Я обнаружил, что способ сделать это: [MarshalAs (UnmanagedType.ByValArray, SizeConst = 20)] public IntPtr [] np ;. Вы можете найти эту ссылку полезной: http: //stackoverflow.com/questions/18647501/marshal-array-of-doubles-from-c-to-c-sharp – PaeneInsula

+0

Я совсем не смущен. Ваш ByValArray ничего не отвечает в этом вопросе. –

+0

Давайте снова прочитаем мой ответ. Я сказал, что «IntPtr является целым числом, которое имеет ту же ширину, что и указатель». И что «ближайший эквивалентный собственный тип IntPtr является void *, нетипизированным указателем». Из этого ясно, что мое понимание IntPtr является солидным. –

Смежные вопросы