Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/263.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#相当于perl`pack(";v";,value)`而将一些值打包到`byte[]`_C#_Perl_Byte_Bytearray_Bytecode - Fatal编程技术网

C#相当于perl`pack(";v";,value)`而将一些值打包到`byte[]`

C#相当于perl`pack(";v";,value)`而将一些值打包到`byte[]`,c#,perl,byte,bytearray,bytecode,C#,Perl,Byte,Bytearray,Bytecode,我试图在我的c代码中复制perl脚本的行为。当我们将任何值转换为字节[]时,无论使用何种语言,其外观都应该相同。所以 我有一个函数调用,在perl中看起来像这样: $diag\u cmd=pack(“V”,长度($s\u部分))$s_部分 其中,$s_par在以下函数中定义。它正在获取.pds文件的位置C:\Users\C\u desaik\Desktop\DIAG\PwrDB\offtarget\data\get\u 8084\u gpio.pds $s_part = sub re

我试图在我的c代码中复制perl脚本的行为。当我们将任何值转换为
字节[]
时,无论使用何种语言,其外观都应该相同。所以

我有一个函数调用,在perl中看起来像这样:

$diag\u cmd=pack(“V”,长度($s\u部分))$s_部分

其中,
$s_par
在以下函数中定义。它正在获取
.pds
文件的位置
C:\Users\C\u desaik\Desktop\DIAG\PwrDB\offtarget\data\get\u 8084\u gpio.pds

$s_part = 

    sub read_pds
    {
       my $bin_s;
       my $input_pds_file = $_[0];
      open(my $fh, '<', $input_pds_file) or die "cannot open file $input_pds_file";
      {
        local $/;
        $bin_s = <$fh>;
      }

  close($fh);
  return $bin_s;

}

但是结果字节数组看起来不一样。我是否必须遵循任何特殊机制来复制
pack(“V”,length($s_part))的行为$s_部分

正如Simon Whitehead提到的,模板字符
V
告诉
pack
将值打包为无符号长(32位)整数(以小尾端顺序)。因此,您需要将字节转换为无符号整数列表(或数组)

例如:

static uint[] UnpackUint32(string filename)
{
    var retval = new List<uint>();

    using (var filestream = System.IO.File.Open(filename, System.IO.FileMode.Open))
    {
        using (var binaryStream = new System.IO.BinaryReader(filestream))
        {
            var pos = 0;
            while (pos < binaryStream.BaseStream.Length)
            {
                retval.Add(binaryStream.ReadUInt32());
                pos += 4;
            }
        }
    }

    return retval.ToArray();
}

更新 如果要读取一个长度前缀字符串或它们的列表,可以使用此函数:

var list = UnpackUint32(@"C:\Users\c_desaik\Desktop\DIAG\PwrDB\offtarget\data\get_8084_gpio.pds");
private string[] UnpackStrings(string filename)
{
    var retval = new List<string>();

    using (var filestream = System.IO.File.Open(filename, System.IO.FileMode.Open))
    {
        using (var binaryStream = new System.IO.BinaryReader(filestream))
        {
            var pos = 0;
            while ((pos + 4) <= binaryStream.BaseStream.Length)
            {
                // read the length of the string
                var len = binaryStream.ReadUInt32();

                // read the bytes of the string
                var byteArr = binaryStream.ReadBytes((int) len);

                // cast this bytes to a char and append them to a stringbuilder
                var sb = new StringBuilder();
                foreach (var b in byteArr)
                    sb.Append((char)b);

                // add the new string to our collection of strings
                retval.Add(sb.ToString());

                // calculate start position of next value
                pos += 4 + (int) len;
            }
        }
    }

    return retval.ToArray();
}
private string[]解压字符串(字符串文件名)
{
var retval=新列表();
使用(var filestream=System.IO.File.Open(filename,System.IO.FileMode.Open))
{
使用(var binaryStream=new System.IO.BinaryReader(filestream))
{
var-pos=0;
而((位置+4)
也可以写成

pack("V/a*", $s_part)
创建长度前缀字符串。长度存储为32位无符号小尾数

+----------+----------+----------+----------+-------- ...
|  Length  |  Length  |  Length  |  Length  | Bytes
| ( 7.. 0) | (15.. 8) | (23..16) | (31..24) |
+----------+----------+----------+----------+-------- ...
以下是如何从字节中重新创建原始字符串:

  • 读取4个字节
  • 如果使用的机器不是little endian机器,
  • 将字节重新排列为本机顺序
  • 将这些字节转换为32位无符号整数
  • 读取与该数字相等的字节数
  • 将字节序列转换为字符串
  • 有些语言提供的工具可以执行这些步骤中的一个以上

    我不懂C#,所以我不能为您编写代码,但我可以用另外两种语言给您举个例子

    在Perl中,这将编写如下:

    sub read_bytes {
       my ($fh, $num_bytes_to_read) = @_;
       my $buf = '';
       while ($num_bytes_to_read) {
          my $num_bytes_read = read($fh, $buf, $num_bytes_to_read, length($buf));
          if (!$num_bytes_read) {
             die "$!\n" if !defined($num_bytes_read);
             die "Premature EOF\n";
          }
    
          $num_bytes_to_read -= $num_bytes_read;
       }
    
       return $buf;
    }
    
    sub read_uint32le { unpack('V', read_bytes($_[0], 4)) }
    sub read_pstr { read_bytes($_[0], read_uint32le($_[0])) }
    
    my $str = read_pstr($fh);
    
    在C中

    int读取字节(文件*fh,无效*buf,大小\u t num\u字节\u至\u读取){
    while(读取的字节数){
    size\u t num\u bytes\u read=fread(buf,1,num\u bytes\u to\u read,fh);
    如果(!num_bytes_read)
    返回0;
    num_bytes_to_read-=num_bytes_read;
    buf+=读取的字节数;
    }
    返回1;
    }
    int read_uint32le(文件*fh,uint32_t*p_i){
    int ok=读取字节(fh,p_i,sizeof(*p_i));
    如果(!ok)
    返回0;
    {/*在非LE机器上重新排列字节*/
    常量char*p=(char*)p_i;
    
    *p_i=(((p[3]文件
    pack
    似乎说
    V
    等同于C#中的无符号32位(
    uint
    )整数…而不是字节。
    +----------+----------+----------+----------+-------- ...
    |  Length  |  Length  |  Length  |  Length  | Bytes
    | ( 7.. 0) | (15.. 8) | (23..16) | (31..24) |
    +----------+----------+----------+----------+-------- ...
    
    sub read_bytes {
       my ($fh, $num_bytes_to_read) = @_;
       my $buf = '';
       while ($num_bytes_to_read) {
          my $num_bytes_read = read($fh, $buf, $num_bytes_to_read, length($buf));
          if (!$num_bytes_read) {
             die "$!\n" if !defined($num_bytes_read);
             die "Premature EOF\n";
          }
    
          $num_bytes_to_read -= $num_bytes_read;
       }
    
       return $buf;
    }
    
    sub read_uint32le { unpack('V', read_bytes($_[0], 4)) }
    sub read_pstr { read_bytes($_[0], read_uint32le($_[0])) }
    
    my $str = read_pstr($fh);
    
    int read_bytes(FILE* fh, void* buf, size_t num_bytes_to_read) {
       while (num_bytes_to_read) {
          size_t num_bytes_read = fread(buf, 1, num_bytes_to_read, fh);
          if (!num_bytes_read)
             return 0;
    
          num_bytes_to_read -= num_bytes_read;
          buf += num_bytes_read;
       }
    
       return 1;
    }
    
    int read_uint32le(FILE* fh, uint32_t* p_i) {
       int ok = read_bytes(fh, p_i, sizeof(*p_i));
       if (!ok)
          return 0;
    
       { /* Rearrange bytes on non-LE machines */
          const char* p = (char*)p_i;
          *p_i = ((((p[3] << 8) | p[2]) << 8) | p[1]) << 8) | p[0];
       }
    
       return 1;
    }
    
    char* read_pstr(FILE* fh) {
       uint32_t len;
       char* buf = NULL;
       int ok;
    
       ok = read_uint32le(fh, &len);
       if (!ok)
          goto ERROR;
    
       buf = malloc(len+1);
       if (!buf)
          goto ERROR;
    
       ok = read_bytes(fh, buf, len);
       if (!ok)
          goto ERROR;
    
       buf[len] = '\0';
       return buf;
    
    ERROR:
       if (p)
          free(p);
    
       return NULL;
    }
    
    
    char* str = read_pstr(fh);