使用PInvoke在C#中等同于C中unsigned char数组的类型

4
我很乐意为您翻译。以下是需要翻译的内容:

我昨天发布了一篇关于将C程序转换为C#作为我的第一个C#项目的帖子,链接在这里:Convert from C to C#, or make DLL?。我已经取得了很多进展,但是卡在了一个部分。我不确定应该如何重新创建这个unsigned char数组。

C代码:

unsigned char state_buf[5125];

//--------------------------------------------------------------------------
// Main of iSerial64
//
void main(int argc, char **argv)
{
   char refresh,buf[200];
   short flag,i,didsetup=0;
   short ROM[9];
   short PortNum,PortType;
   long SHandle;
   char serialtmp[2], serial[10][17];
   int j = -1;

以下是使用PInvoke在C#中调用state_buf函数的代码,详见http://files.maximintegrated.com/sia_bu/licensed/docs/1-wire_sdk_win/TMEX/romm1rxq.html

C#代码:

 [DllImport("IBFS64.dll")]
        public static extern short TMRom(
            int session_handle,
            byte state_buf,
            [MarshalAs(UnmanagedType.LPStr)]StringBuilder ROM
        );

我看到byte是C#的等价物,但我不完全确定如何使用它。
你们迄今为止非常有帮助,我对自己在这方面取得的进展感到非常满意。
这是我昨天以来在C#中完成的工作:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace PInvokeTest {
  class Program {
    static void Main(string[] args)
      {
          int session_handle = 0;
          int result = 0;
          int flag = 0;
          int didsetup = 0;
          int defPort = 0;
          int i = 0, j = -1;
          short type_test = 0;
          byte state_buf = 0;
          short port_num = 0, port_type = 1;
          StringBuilder ID_buf = new StringBuilder();
          StringBuilder serial = new StringBuilder();
          StringBuilder serialtmp = new StringBuilder();
          StringBuilder ROM = new StringBuilder();

          //result = TMSearch(session_handle, state_buffer, 1, 1, 0xEC);


          defPort = TMReadDefaultPort(out port_num,out port_type);


          if (defPort == 1)
          {
              Console.Write("Default Device: ");

              switch (port_type)
              {
                  case 1:
                      Console.Write("DS9097E serial adapter ");
                      break;

                  case 2:
                      Console.Write("Parallel adapter ");
                      break;

                  case 5:
                      Console.Write("DS90907U serial adapter ");
                      break;

                  case 6:
                      Console.Write("DS9490 USB adapter ");
                      break;
              }
              Console.Write("on port # {0}", port_num);
          }

          else
              Console.Write("No Device found");

          // get the TMEX driver version
          Get_Version(ID_buf);

          Console.WriteLine("\nDriver: {0}", ID_buf);

          type_test = TMGetTypeVersion(port_type, ID_buf);

          if (type_test < 0)
          {
              Console.WriteLine("\nNo Hardware Driver for this type found!\n");
              Console.Write("Press any key to exit");
              Console.ReadKey();
              Environment.Exit(0);
          }
          else
              Console.WriteLine("Driver Found");


          // check for valid range of PortNum
          if ((port_num < 1) || (port_num > 15))
          {
              Console.WriteLine("ERROR, invalid port requested: {0}\n", port_num);
              Console.Write("Press any key to exit");
              Console.ReadKey();
              Environment.Exit(0);
          }


          do
          {
              // get a session handle to the requested port
              session_handle = TMExtendedStartSession(port_num, port_type, IntPtr.Zero);

              if (session_handle > 0)
              {
                  // check to see if TMSetup has been done once
                  if (didsetup == 0)
                  {
                      flag = TMSetup(session_handle);
                      if (flag == 1 || flag == 2)
                      {
                          Console.Write("TMSetup complete {0}", flag);
                          didsetup = 1;
                      }
                      else
                      {
                          Console.Write("ERROR doing setup {0}", flag);
                          break;
                      }
                  }

                  else
                  {
                      //j was added to keep track of the serial number strings
                      j++;

                      //memset(serial[j], 0, strlen(serial[j]));
                      flag = TMNext(session_handle, state_buf);
                      if (flag > 0)
                      {
                          //ROM[0] = 0;
                          flag = TMRom(session_handle, state_buf, ROM);
                          for (i = 7; i >= 0; i--)
                          {
                              //This section was changed from the original
                              //copies raw number into string
                              //sprintf(serialtmp, "%02X", ROM[i]);
                              //strcat(serial[j], serialtmp);

                          }
                          Console.WriteLine("{0} \n", serial[j]);

                      }
                      else
                          Console.WriteLine("end of search\n");
                  }
                  // close the opened session
                  TMEndSession(session_handle);
              }

          }
          while (flag > 0);






          Console.ReadKey();
      }

   [DllImport("IBFS64.dll")]
    public static extern int TMExtendedStartSession(
        short PortNum, 
        short PortType,
        IntPtr EnhancedOptions 
    );

    [DllImport("IBFS64.dll")]
    public static extern short TMSearch(
        int session_handle, 
        byte state_buffer, 
        short p1, 
        short p2, 
        short p3
    );

    [DllImport("IBFS64.dll")]
    public static extern short TMReadDefaultPort(
        out short port_num,
        out short port_type
    );

    [DllImport("IBFS64.dll")]
    public static extern short Get_Version(
        [MarshalAs(UnmanagedType.LPStr)]StringBuilder ID_buf 
    );

    [DllImport("IBFS64.dll")]
    public static extern short TMGetTypeVersion(
        short port_type,
        [MarshalAs(UnmanagedType.LPStr)]StringBuilder ID_buf
    );

    [DllImport("IBFS64.dll")]
    public static extern short TMSetup(
        int session_handle
    );

    [DllImport("IBFS64.dll")]
    public static extern short TMNext(
        int session_handle,
        byte state_buf
    );

    [DllImport("IBFS64.dll")]
    public static extern short TMRom(
        int session_handle,
        byte state_buf,
        [MarshalAs(UnmanagedType.LPStr)]StringBuilder ROM
    );

    [DllImport("IBFS64.dll")]
    public static extern short TMEndSession(
        int session_handle
    );
  }
}

如果有需要修改的地方,请告诉我。感谢您的帮助!


关于你应该改变的事情,P/Invoke方法应该放在它们自己的专门类型中,你应该将主方法拆分为单独的方法和类型。 - Magus
第二个参数是byte[]。第三个参数是short[],有8个元素,而不是9个。您真的需要记录API,以便没有人需要猜测,只需提供一个链接。这里是链接 - Hans Passant
第二个参数可能是IntPtr。很难判断。 - David Heffernan
1个回答

10

对于 C 语言数组:

unsigned char state_buf[5125] ;

尝试使用C#

byte[] state_buf = new byte[5125] ;

byte是一个无符号的8位数字,范围为0到255。如果您想要有符号的八位字节,请使用sbyte(范围为-128到+127)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接