Если вы не хотите использовать PChar на стороне Delphi, лучше всего использовать массив символов фиксированной длины.Тем не менее, тип PChar специально создан для обработки таких ситуаций: это строка в C-стиле, заканчивающаяся NULL.Для ясности в вашем определении C # вы можете использовать атрибут MarshalAs
, чтобы точно указать, какую «строку» вы ожидаете на сайте вызова.Значение по умолчанию для строки внутри структуры зависит от того, какую версию Framework вы используете: Compact Framework поддерживает только строки Unicode (LPWSTR), в противном случае это будет LPSTR.Поскольку существует 7 различных вариантов маршалинга строк, я всегда указываю тот, который мне нужен, даже если это значение по умолчанию, но я думаю, что в вашем случае это необязательно.
Кроме того, как отмечалось выше, тип C # Color не являетсятакой же, как тип Delphi TColor.TColor - это просто целое число в странном смешанном формате, в то время как Color имеет множество дополнительных свойств, помимо цветов RGB.У вас есть несколько вариантов: определить новую структуру C #, соответствующую определению TColor, или просто использовать int и создавать значения вручную.Вот лучшее описание структуры TColor .
Наконец, для типов значений, таких как struct, вам на самом деле не нужно создавать их экземпляры с помощью new
;если вы просто объявляете переменную типа структуры, пространство выделяется для вас.Единственное преимущество использования new
для создания экземпляра структуры состоит в том, что ваш конструктор будет работать (у вас его нет), и все поля будут инициализированы до значений по умолчанию.Если вы все равно планируете заполнить все поля, вам не нужны только накладные расходы.
В целом, это то, что я, вероятно, использовал бы:
public struct MyOtherRecord
{
public IntPtr SomeDC;
public int SomeOtherInt;
}
public struct MyRecord
{
public int SomeInteger;
public int SomeColor;
[MarshalAs(UnmanagedType.LPSTR)] public string SomeText;
public int SomeTextSize;
public MyOtherRecord OtherRecord;
}
Одна вещь, которой я не являюсьуверен, это выравнивание записи.Мне кажется, я помню, что читал, что Delphi «в теории» по умолчанию использовал 8-байтовое выравнивание, но «на практике» он выравнивал поля в зависимости от их типа;это контролируется директивой $ {A}.В C #, если вы не используете явный [StructLayout]
, ваши поля получат выравнивание на основе их размера.Все в ваших записях является целочисленным значением, поэтому вы должны быть в безопасности, но если вы видите, что выглядит как повреждение данных, проверьте значения «sizeof» для структур Delphi и C # и убедитесь, что они одинаковы.
Если нет, вы можете использовать атрибуты [StructLayout (LayoutKind.Explicit)] и [FieldOffset], чтобы точно указать выравнивание вашей структуры C #.
ОБНОВЛЕНИЕ:
Благодаря@David Heffernan за указание на то, что PChar в Delphi 7 - это LPSTR (в этом случае мое личное предпочтение будет заключаться в том, чтобы использовать PWideChar в Delphi, поскольку .NET CF не поддерживает ANSI, а Windows в любом случае использует UTF-16, нокакой бы ни работал.) Ответ обновлен для соответствия.