.NET Interop IntPtr vs. ref

Prawdopodobnie pytanie noob, ale interop nie jest jeszcze jedną z moich mocnych stron.

Czy poza ograniczeniem liczby przeciążeń powinienem zadeklarować moje DllImports jak:

[DllImport("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, int msg, int wParam, IntPtr lParam);

I używaj ich w ten sposób:

IntPtr lParam = Marshal.AllocCoTaskMem(Marshal.SizeOf(formatrange));
Marshal.StructureToPtr(formatrange, lParam, false);

int returnValue = User32.SendMessage(_RichTextBox.Handle, ApiConstants.EM_FORMATRANGE, wParam, lParam);

Marshal.FreeCoTaskMem(lParam);

Zamiast tworzyć ukierunkowane przeciążenie:

[DllImport("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, int msg, int wParam, ref FORMATRANGE lParam);

I używając tego jak:

FORMATRANGE lParam = new FORMATRANGE();
int returnValue = User32.SendMessage(_RichTextBox.Handle, ApiConstants.EM_FORMATRANGE, wParam, ref lParam);

Przeciążenie przez ref staje się łatwiejsze w użyciu, ale zastanawiam się, czy jest wada, o której nie wiem.

Edytować:

Jak dotąd mnóstwo świetnych informacji.

@P Daddy: Czy masz przykład bazowania klasy struct z abstrakcyjnej (lub dowolnej) klasy? Zmieniłem swój podpis na:

[DllImport("user32.dll", SetLastError = true)]
public static extern int SendMessage(IntPtr hWnd, int msg, int wParam, [In, Out, MarshalAs(UnmanagedType.LPStruct)] CHARFORMAT2 lParam);

BezIn, Out, iMarshalAs SendMessage (EM_GETCHARFORMAT w moim teście) kończy się niepowodzeniem. Powyższy przykład działa dobrze, ale jeśli zmienię go na:

[DllImport("user32.dll", SetLastError = true)]
public static extern int SendMessage(IntPtr hWnd, int msg, int wParam, [In, Out, MarshalAs(UnmanagedType.LPStruct)] NativeStruct lParam);

Otrzymuję wyjątek System.TypeLoadException, który mówi, że format CHARFORMAT2 jest nieprawidłowy (spróbuję przechwycić go tutaj).

Wyjątek:

Nie można załadować typu „CC.Utilities.WindowsApi.CHARFORMAT2” z zespołu „CC.Utilities, Version = 1.0.9.1212, Culture = neutral, PublicKeyToken = 111aac7a42f7965e”, ponieważ format jest nieprawidłowy.

Klasa NativeStruct:

public class NativeStruct
{
}

próbowałemabstract, dodającStructLayout atrybut itp. i otrzymuję ten sam wyjątek.

[StructLayout(LayoutKind.Sequential)]
public class CHARFORMAT2: NativeStruct
{
    ...
}

Edytować:

Nie śledziłem FAQ i zadałem pytanie, które można omówić, ale nie otrzymałem pozytywnej odpowiedzi. Oprócz tego w tym wątku było wiele wnikliwych informacji. Więc pozostawiam czytelnikom głosowanie nad odpowiedzią. Najpierw będzie odpowiedź od 1 do ponad 10 głosów w górę. Jeśli żadna odpowiedź nie spełni tego w ciągu dwóch dni (12/17 PST), dodam własną odpowiedź, która podsumowuje całą pyszną wiedzę w wątku :-)

Edytuj ponownie:

Skłamałem, akceptując odpowiedź P Daddy, ponieważ jest on mężczyzną i był wielką pomocą (ma też uroczą małpkę :-P)

questionAnswers(5)

yourAnswerToTheQuestion