Функция p / invoke C, которая возвращает указатель на структуру - PullRequest
4 голосов
/ 23 апреля 2009

Как мне объявить в C # функцию C, которая возвращает указатель на структуру?

Я полагаю, что одним из способов сделать это является следующее, а затем Marshal.PtrToStructure , чтобы получить фактическое значение структуры.

// C-function
SimpleStruct * Function(void);

// C# import
[DllImport("MyDll.dll")]
public static extern IntPtr Function();
  1. Правильно ли я об этом?
  2. Есть ли другие способы сделать то же самое? (Было бы нормально вернуть структуру по значению)

Ответы [ 3 ]

4 голосов
/ 23 апреля 2009

Поскольку функция возвращает указатель (надеюсь, не локально выделенный?), Лучше всего его вручную маршалировать (через Marshal.PtrToStructure ).

Если бы это был параметр, вы могли бы создать управляемую версию структуры с помощью PInvoke Interop Assistant, а затем передать ее через ref или out.

4 голосов
/ 23 апреля 2009

Предупреждение: это будет работать только в том случае, если возвращаемый указатель находится в памяти, уже управляемой CLR

Я верю, что вы ищете

// C# import
[DllImport("MyDll.dll")]
[return : MarshalAs(UnmanagedType.LPStruct)]
public static extern StructureName Function();

[StructLayout(LayoutKind.Sequential)]
public class StructureName {}

Это должно устранить необходимость каких-либо ручных Marshal.PtrToStructure вызовов. В зависимости от того, что содержит ваша структура, вам может потребоваться пометить некоторые поля атрибутами MarshalAs в зависимости от ситуации. MSDN имеет хороший пример этого.

0 голосов
/ 23 апреля 2009

Я здесь вообще не эксперт, но мне довелось посмотреть на фрагмент кода (который я не совсем понимаю), который делает то же самое.

Вот что они делают

[DllImport("")]
private static extern short MethodName([In,Out] ref StructureName variable);

, а затем в структуре они имеют следующий атрибут

[StructLayout(LayoutKind.Sequential, Size = #)]
public struct StructureName {}

Я думаю, что часть, которую вы ищете, это часть [In, Out], и, поскольку она передается через ref, вы должны получать те же данные обратно.

помечен как вики сообщества, чтобы люди могли исправить это, если ошиблись.

...