.NET Interop IntPtr против реф
Вероятно, вопрос нуба, но взаимодействие пока не является моей сильной стороной.
Помимо ограничения количества перегрузок, есть ли причина, по которой я должен объявить свои DllImports как:
[DllImport("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, int msg, int wParam, IntPtr lParam);
И используйте их так:
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);
Вместо создания целевой перегрузки:
[DllImport("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, int msg, int wParam, ref FORMATRANGE lParam);
И используя это как:
FORMATRANGE lParam = new FORMATRANGE();
int returnValue = User32.SendMessage(_RichTextBox.Handle, ApiConstants.EM_FORMATRANGE, wParam, ref lParam);
Перегрузка по ref в итоге становится проще в использовании, но мне интересно, есть ли недостаток, о котором я не знаю.
Редактировать:
Пока что много интересной информации, ребята.
@P Папа: У вас есть пример создания класса struct из абстрактного (или любого) класса? Я изменил свою подпись на:
[DllImport("user32.dll", SetLastError = true)]
public static extern int SendMessage(IntPtr hWnd, int msg, int wParam, [In, Out, MarshalAs(UnmanagedType.LPStruct)] CHARFORMAT2 lParam);
БезIn
, Out
, а такжеMarshalAs
SendMessage (EM_GETCHARFORMAT в моем тесте) завершается ошибкой. Приведенный выше пример хорошо работает, но если я изменю его на:
[DllImport("user32.dll", SetLastError = true)]
public static extern int SendMessage(IntPtr hWnd, int msg, int wParam, [In, Out, MarshalAs(UnmanagedType.LPStruct)] NativeStruct lParam);
Я получаю исключение System.TypeLoadException, в котором говорится, что формат CHARFORMAT2 недопустим (я постараюсь записать его здесь).
Исключение:
Не удалось загрузить тип 'CC.Utilities.WindowsApi.CHARFORMAT2' из сборки 'CC.Utilities, версия = 1.0.9.1212, Culture = нейтральный, PublicKeyToken = 111aac7a42f7965e', так как формат недопустим.
Класс NativeStruct:
public class NativeStruct
{
}
я пробовалabstract
, добавивStructLayout
атрибут и т. д. и я получаю то же исключение.
[StructLayout(LayoutKind.Sequential)]
public class CHARFORMAT2: NativeStruct
{
...
}
Редактировать:
Я не следил за часто задаваемыми вопросами и задал вопрос, который можно обсудить, но на который нет положительного ответа. Кроме того, в этой теме было много полезной информации. Поэтому я оставлю это на усмотрение читателей, чтобы проголосовать за ответ. Первым от 10 до 10 голосов будет ответ. Если в течение двух дней ни один ответ не встретится с этим (12/17 по тихоокеанскому времени), я добавлю свой собственный ответ, который суммирует все вкусные знания в теме :-)
Изменить снова:
Я солгал, принимая ответ P Daddy, потому что он - человек, и он мне очень помог (у него тоже есть симпатичная маленькая обезьянка :-P)