Я пытаюсь преобразовать код C++ в C#
#pragma pack (push, 1)
typedef struct od
{
unsigned short Reserved1;
unsigned char Reserved2;
od()
: Reserved1(0)
, Reserved2(0)
{}
} OD;
typedef struct PortValue
{
USHORT pIndex;
USHORT value;
ULONG32 ticks;
PortValue()
: pIndex(0)
, value(0)
, ticks(0)
{}
} PORT_VALUE, *PPORT_VALUE;
typedef struct _API_Data
{
unsigned long Ticks;
unsigned long SystemTime;
unsigned short DisableNotification;
unsigned short Reserved2;
unsigned short NextValue;
unsigned short Reserved3;
PORT_VALUE PortValues[500];
OD Reserved4;
_API_Data()
: Ticks(0)
, SystemTime(0)
, DisableNotification(0)
, Reserved2(0)
, NextValue(0)
, Reserved3(0)
{}
} API_DATA, *PAPI_DATA;
#pragma pack (pop)
Вот что я придумал для C#, но, как вы увидите ниже, это неправильно.
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct od
{
public ushort Reserved1;
public byte Reserved2;
} OD;
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct PortValue
{
public ushort pIndex;
public ushort value;
public uint ticks;
} PORT_VALUE, *PPORT_VALUE;
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct _API_Data
{
uint Ticks;
uint SystemTime;
ushort DisableNotification;
ushort Reserved2;
ushort NextValue;
ushort Reserved3;
PORT_VALUE PortValues[500];
OD Reserved4;
} API_DATA, *PAPI_DATA;
Я знаю, что мой код C# неверен в том, как я объявляю структуры.
Я не знаю, как создать эквивалент имени структуры и указателя на структуру.
Я также не знаю, как инициализировать значения, как это делает код C++.
Любая помощь будет принята с благодарностью.
Я также не знаю, как инициализировать значения, как это делает код C++. -- Вы инициализируете элементы в структуре C# так же, как вы всегда делаете это в C#. Нет необходимости рассматривать, как C++ инициализирует члены.
Структуры C# не имеют отдельных указателей/имен, как C++, просто назовите структуру именно так, как вы хотите.
Кроме того, typedef struct
является пережитком C
. В C++ нет необходимости в typedef struct
, только struct
. То, что у вас есть, даже не является структурами C
, поскольку структуры содержат определяемый пользователем конструктор, а их нет в C
. Если бы это было C
, вы не смогли бы инициализировать ни один из этих членов так, как вы опубликовали — вместо этого вам пришлось бы вызвать функцию для «обнуления» всех членов, например, с помощью memset
.
Насколько хорошо вы знаете C++ и насколько хорошо вы знаете C#. В общем, НЕ конвертируйте код с одного языка на другой. Но попытайтесь понять, что делает код C++, а затем напишите новый код на C#.
Если ваш код C++ вызывает функцию Windows API, есть большая вероятность, что C# имеет какой-то собственный код... так что можете ли вы сказать нам, ЧТО вы пытаетесь сделать, вместо того, чтобы спрашивать, КАК что-то сделать?
@Raildex Я думаю, чтобы вызвать код из C++ (или наоборот)
Продолжая точку зрения @PepijnKramer, вам следует действительно описать свой вариант использования. Я предполагаю, что эти структуры будут использоваться в каком-то сценарии P/Invoke. Ваш вопрос должен включать код, который будет использовать эти структуры, и описывать, что/почему вы это делаете.
В C# нет эквивалента typedef
структуры, и вам в любом случае не нужно объявлять псевдонимы указателей на тип структуры.
Попробуйте еще что-нибудь вроде этого:
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct OD
{
public ushort Reserved1 = 0;
public byte Reserved2 = 0;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct PORT_VALUE
{
public ushort pIndex = 0;
public ushort value = 0;
public uint ticks = 0;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct API_DATA
{
public uint Ticks = 0;
public uint SystemTime = 0;
public ushort DisableNotification = 0;
public ushort Reserved2 = 0;
public ushort NextValue = 0;
public ushort Reserved3 = 0;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 500)]
public PORT_VALUE[] PortValues = new PORT_VALUE[500];
public OD Reserved4 = new OD();
}
Спасибо, Реми. Как всегда вы очень помогаете. Единственное, что нужно было добавить в приведенный выше код, это пустой конструктор, необходимый для каждой структуры (например, public OD() {})
@Гэри Почему? В этом нет необходимости, поскольку поля инициализируются напрямую.
Компилятор Visual Studio захотел этого и сказал, что без него будет ошибка. «Ошибка CS8983: структура с инициализаторами полей должна включать явно объявленный конструктор». Почему VS настаивает на пустом конструкторе, который ничего не делает, я сказать не могу.
почему вы пытаетесь сохранить аналог C# таким же, как и в C++?