2014-01-04 3 views
0

Мой неуправляемого C++ DLL имеет функцию с ТОЧКИ из параметров:PInvoke и POINT

void GetPosition(int iItemIndex, POINT *pt) 

Я пытаюсь PInvoke функцию в моей C приложения #:

[DllImport(@"unmanaged.dll")] 
public static extern void GetPosition(int iItemIndex, System.Drawing.Point pt); 

Мой вопрос, должен Я использую System.Drawing.Point как эквивалент C# для POINT? Модификация неуправляемого кода является опцией. Должен ли я использовать два long s вместо этого?

void GetPosition(int iItemIndex, long *x, long *y) 
+3

Я бы рекомендовал Struct с теми же элементами, что и POINT –

+3

http://www.pinvoke.net/default.aspx/Structures/POINT.html. Пример внедрения и заметьте, что ваш метод в порядке. – chris

ответ

2

POINT представляет собой структуру С, ее PInvoke эквивалент С # структура с двумя элементами типа INT. System.Drawing.Point уже является отличным кандидатом, не нужно писать самостоятельно.

Опасайтесь, однако, что ваша декларация C# неверна. Объявление C использует POINT *, указатель на структуру POINT. C объявлениями часто являются неоднозначный. Это может означать, что POINT передается по ссылке, так что функция заполняет элементы. Или может означать, что вызывающий объект должен передать массив структур POINT. Так что либо из этих двух заявлений C# будет матч:

public static extern void GetPosition(int iItemIndex, out Point pt); 
    public static extern void GetPosition(int iItemIndex, Point[] points); 

версия массива весьма маловероятно, вы бы ожидать, что C программист использовать множественное число GetPositions(). И есть проблема в том, что он не будет знать, насколько велик массив, массивы C очень примитивны и не имеют свойства испеченной длины.

Так, конечно, правильная декларация:

[DllImport(@"unmanaged.dll", CallingConvention=CallingConvention.Cdecl)] 
    public static extern void GetPosition(int iItemIndex, out Point pt); 

Обратите внимание, что я добавил свойство CallingConvention, то по умолчанию для кода C. Удалите его, если вы точно знаете, что он использует __stdcall.

+0

Но, если я напишу свою собственную структуру с двумя членами типа int, как PInvoke знает, какой из членов назначить 'POINT.x' и какой из них назначить' POINT.y'? Нужно ли мне указывать члены 'x' и' y'? – Spookbuster

+1

Нет, маркерщик pinvoke не знает, что такое имена C, все, что он может видеть, - это ваша декларация. Структуры копируются по полю, имя не имеет значения. Если это очень простая структура, такая как эта, то она * blittable *, простая копия памяти выполняет эту работу. –