【发布时间】:2021-04-20 21:06:35
【问题描述】:
我需要帮助将部分 C# 代码翻译成 Delphi。 我非常感谢任何帮助或建议。
unsafe {
fixed (byte* bpt = &buff[140]) {
byte b1 = bpt[0];
byte b2 = bpt[1];
byte b3 = bpt[2];
byte b4 = bpt[3];
}
}
我尝试了几种方法,用 4 字节变量定义记录,定义 tbytearray,但似乎没有什么是正确的。
对此有什么想法吗?
谢谢。
更新
由于我似乎没有正确定义我的问题,因为这是我的第一个问题,所以这里是 C# 上的完整函数。
private void ProcessCommAlarm_V40(ref CHCNetSDK.NET_DVR_ALARMER pAlarmer, IntPtr pAlarmInfo, uint dwBufLen, IntPtr pUser)
{
MyDebugInfo AlarmInfo = new MyDebugInfo(DebugInfo);
byte[] buff = new byte[dwBufLen];
System.Runtime.InteropServices.Marshal.Copy(pAlarmInfo, buff, 0, (int)dwBufLen);
string sBuff = "";
if (dwBufLen - 140 > 0 && (dwBufLen - 140) % 4 == 0)
{
int msgType = BitConverter.ToInt32(buff, 0);
string sMsgType = "";
bool bAcceptedMsg = false;
int nTargetType = 0;
switch (msgType)
{
case 2:
sMsgType = "Video Loss"; bAcceptedMsg = true; nTargetType = 1; break;
case 3:
sMsgType = "Motion"; nTargetType = 1; break;
}
if (bAcceptedMsg)
{
int nTotalElements = BitConverter.ToInt32(buff, 12);
if ((nTargetType == 1 && nTotalElements <= CHCNetSDK.MAX_CHANNUM_V30) || (nTargetType == 2 && nTotalElements <= CHCNetSDK.MAX_DISKNUM_V30))
{
int len = nTotalElements * 4;
byte[] channels = new byte[len];
unsafe
{
fixed (byte* bpt = &buff[140])
{
byte b1 = bpt[0];
byte b2 = bpt[1];
byte b3 = bpt[2];
byte b4 = bpt[3];
IntPtr dwDataAddress = new IntPtr(b1 + b2 * (1 << 8) + b3 * (1 << 16) + b4 * (1 << 24));
System.Runtime.InteropServices.Marshal.Copy(dwDataAddress, channels, 0, len);
}
}
for (int i = 0; i <= len - 4; i += 4)
{
sBuff += string.Format("Channel No: {0}", BitConverter.ToInt32(channels, i));
sBuff += Environment.NewLine;
}
}
}
}
}
现在,这就是我到目前为止所做的,其中包括给我的@remy-lebeau 所做的更改。
procedure ProcessCommAlarm_V40(pAlarmer: LPNET_DVR_ALARMER; pAlarmInfo: PChar; dwBufLen: DWORD; dwUser: DWORD);
var
buff: array of byte;
msgType: Integer;
sMsgType: String;
bAcceptedMsg: Boolean;
nTargetType: Integer;
sBuff: String;
nTotalElements: Integer;
channels: array of byte;
len: Integer;
b1,b2,b3,b4:byte;
bpt: pbyte;
dwDataAddress: IntPtr;
I: Integer;
begin
sBuff := '';
SetLength(buff, dwBufLen);
CopyMemory(buff, pAlarmInfo, dwBufLen);
if (dwBufLen - 140 > 0) and ((dwBufLen - 140) mod 4 = 0) then begin
msgType := Integer(buff[0]);
sMsgType := '';
bAcceptedMsg := false;
nTargetType := 0;
case (msgType) of
2:
begin
sMsgType := 'Video loss';
bAcceptedMsg := true;
nTargetType := 1;
end;
end;
if (bAcceptedMsg) then
begin
nTotalElements := buff[12];
if ((nTargetType = 1) and (nTotalElements <= MAX_CHANNUM_V30)) or ((nTargetType = 2) and (nTotalElements <= MAX_DISKNUM_V30)) then begin
len := nTotalElements * 4;
SetLength(channels,len);
bpt := @buff[140];
b1 := bpt[0];
b2 := bpt[1];
b3 := bpt[2];
b4 := bpt[3];
dwDataAddress := IntPtr(b1 + b2 * (1 shl 8) + b3 * (1 shl 16) + b4 * (1 shl 24));
sBuff := sBuff + IntToStr(dwDataAddress);
sBuff := sBuff + #10 + #13;
CopyMemory(Channels, @dwDataAddress, len);
I:=0;
while (i <= len - 4) do begin
sBuff := sBuff + 'Channel No: ' + IntToStr(channels[i]);
sBuff := sBuff + #13 + #10;
i:= i + 4;
end;
end;
end
end;
end;
有人可以重新检查翻译,因为 Delphi 代码无法重现与 C# 相同的结果。
更新:
阅读下面@Remy 写下的详细解释后,我能够在 C# 和 Delphi 中的两个应用程序上重现相同的结果。
现在正在运行的代码如下。
procedure ProcessCommAlarm_V40(pAlarmer: LPNET_DVR_ALARMER; pAlarmInfo: IntPtr; dwBufLen: DWORD; dwUser: IntPtr);
var
buff: array of byte;
channels: array of byte;
msgType: Integer;
sMsgType: String;
bAcceptedMsg: Boolean;
nTargetType: Integer;
sBuff: String;
nTotalElements: Integer;
len: Integer;
b1,b2,b3,b4:byte;
bpt: pbyte;
dwDataAddress: IntPtr;
I: Integer;
x:pbyte;
begin
Form1.Memo1.Lines.Add(FormatDateTime('H:m:s',now));
sBuff := '';
SetLength(buff, dwBufLen);
CopyMemory(buff, Pointer(pAlarmInfo), dwBufLen);
if (dwBufLen - 140 > 0) and ((dwBufLen - 140) mod 4 = 0) then begin
msgType := Integer(buff[0]);
sMsgType := '';
bAcceptedMsg := false;
nTargetType := 0;
case (msgType) of
2:
begin
sMsgType := 'Video loss';
bAcceptedMsg := true;
nTargetType := 1;
end;
end;
if (bAcceptedMsg) then
begin
nTotalElements := buff[12];
if ((nTargetType = 1) and (nTotalElements <= MAX_CHANNUM_V30)) or ((nTargetType = 2) and (nTotalElements <= MAX_DISKNUM_V30)) then begin
len := nTotalElements * 4;
SetLength(channels,len);
bpt := @buff[140];
b1 := bpt[0];
b2 := bpt[1];
b3 := bpt[2];
b4 := bpt[3];
dwDataAddress := IntPtr(b1 + b2 * (1 shl 8) + b3 * (1 shl 16) + b4 * (1 shl 24));
CopyMemory(Channels, Pointer(dwDataAddress), len);
I:=0;
while (i <= len - 4) do begin
sBuff := sBuff + 'Channel No: ' + IntToStr(channels[i]);
sBuff := sBuff + #13 + #10;
i:= i + 4;
end;
end;
end
end;
end;
【问题讨论】:
-
你应该展示你所做的并告诉你如何验证它是否正确。
-
@fpiette,感谢您的评论,我很抱歉,这是我的第一篇文章。我已经更新了问题。
-
这不是翻译服务。
-
是的,谢谢,我知道这一点,但是我现在在超过 20000 行的项目中被困在这部分代码上 10 天。所以,我知道这不符合规则,我知道我的要求很高,但我真的需要在这个领域比我更有经验的人的帮助。
-
@Mark 您是否尝试过调试代码以查看其行为与您的预期有何不同?这是一个问答网站,而不是调试服务。您应该专注于具体问题。
标签: c# delphi code-translation