에 포장 된 기록과 같은 방식으로 정렬 화 배열을 바이트 :는 C# 구조체는이 같은 바이트 배열을 생성 델파이 2007로 작성된 기존 응용 프로그램이 델파이
command_data = packed record
direction : word;
name : array [0..9] of char;
end;
command_header = packed record
length : word;
data1 : word;
data2 : cardinal;
end;
command_data_container = packed record
data : command_data;
containerId : word;
end;
function Generate(name: string)boolean;
var
header : command_header;
container : command_data_container;
charArrayName: array [0..9] of char;
begin
charArrayName = array [0..9] of char;
for I := 0 to Length(name) - 1 do begin
charArrayName[i] := name[i+1];
end;
charArrayName[i+1] := #0;
header.length := sizeof(header) + sizeof(container);
header.data1 := 0;
header.data2 := 1;
container.data.direction := 1;
container.data.name := charArrayName;
container.containerId := 1;
stream := TMemoryStream.Create;
stream.WriteBuffer(header, SizeOf(header));
stream.WriteBuffer(container, SizeOf(container));
//...
end;
나는 C#에서이 부분을 다시 작성해야합니다. 지금까지이있어 :
[StructLayout(LayoutKind.Sequential, Pack = 1)]
unsafe struct command_data
{
public ushort direction;
public fixed char name[10];
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
unsafe struct command_header
{
public ushort length;
public ushort data1;
public ulong data2;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct command_data_container
{
public command_data data;
public ushort containerId;
}
public bool Generate(string name)
{
name = name + Char.MinValue; // Add null terminator.
char[] charArrayName = agentId.ToCharArray();
unsafe
{
command_header header;
command_data_container command;
header.data1 = 0;
header.data2 = 1;
header.length = (ushort)(sizeof(command_header) + sizeof(command_data_container));
command.data.direction = 1;
*command.data.name = charArrayName[0];
for (int i = 1; i < charArrayName.Length; i++)
{
*(command.data.name + i) = charArrayName[i];
}
command.containerId = 1;
var headerBytes = StructToBytes<command_header>(header);
var commandBytes = StructToBytes<command_data_container>(command);
byte[] combined = new byte[headerBytes.Length + commandBytes.Length];
Buffer.BlockCopy(headerBytes, 0, combined, 0, headerBytes.Length);
Buffer.BlockCopy(commandBytes, 0, combined, headerBytes.Length, commandBytes.Length);
//combined should have the same data as the stream in the delphi code
}
}
public static byte[] StructToBytes<T>(T structure) where T : struct
{
int size = Marshal.SizeOf(structure);
byte[] rawData = new byte[size];
GCHandle handle = GCHandle.Alloc(rawData, GCHandleType.Pinned);
try
{
IntPtr rawDataPtr = handle.AddrOfPinnedObject();
Marshal.StructureToPtr(structure, rawDataPtr, false);
}
finally
{
handle.Free();
}
return rawData;
}
나는 바이트 배열에 구조체를 변환하는 여러 가지 방법을 시도하지만, 그들 중 누구도 델파이 코드와 같은 결과를 재현하지 않습니다. C# performance - Using unsafe pointers instead of IntPtr and Marshal
가 나는 또한 SO에서 방법을 마샬링 일부 다른 시도했지만 아무 일하지 :
StructToBytes 방법은 여기에서 차용된다. 내가 뭘 잘못 했니?
Delphi 2007 Char는 AnsiChar이고 C#은 유니 코드입니까? –
C#의 Char는 2 바이트이며 C++에서는 1 바이트입니다. 그래서 C#에서 사용 : 새 바이트 [10]. 또한 배열은 '\ 0'(0x00)으로 끝나야합니다. 나는 보통 다음과 같이 사용한다 : Encoding.UTF8.GetBytes ("JohnSmith \ 0"); – jdweng
** ** C#에서 this를 다시 작성해야한다면 interop 및 marshalling에 대해 왜 신경을 씁니까? 같은 바이트 수를 생성하면됩니다. 너무 어려울 수 없습니다. –