我在从外部dll例程接收数据时遇到问题。 dll是从微控制器芯片读取数据。这在Delphi中工作正常,我正在尝试使其在C#中工作。

地址:起始地址
Len:读取数据的总长度

该函数返回一个TData数组,其中索引为0的项包含开始
地址,索引为1的项目包含接收到的数据的长度。以下
项目(索引2和更高)包含收到的数据。如果接收操作失败,则
数组中返回的长度值设置为零

  [DllImport("dsio.dll", CallingConvention = CallingConvention.StdCall)]
  [return: MarshalAs(UnmanagedType.LPArray)]
  public static extern byte[] Receive(int Adr, int Len);

  private void BtnReceive_Click(object sender, EventArgs e)
     {
         byte[] Data = new byte[256];
         int Adr = 0x05;
         int Len = 8;

         Data = Receive(Adr, Len);
         txtBox2.Text = Data;
     }

最佳答案

首先,由于将new byte[256]设置为Data的返回结果,因此无需实例化Receive()

您应该尝试删除[return: MarshalAs]属性,以查看默认编组是否起作用。

如果不起作用,则this documentation指示在使用SizeConst时,还应在SizeParamIndex属性声明中设置MarshalAsUnmanagedType.LPArray。我不知道您是否需要使用其中一个或两个参数(请阅读链接的文档和实验)。如果需要,SizeParamIndex将为1,因为第二个参数是长度。

[return: MarshalAs( UnmanagedType.LPArray, SizeConst = 256, SizeParamIndex = 1 )]


附录:由于您将TData声明为类型,因此使我有了一个想法,即在C#中使用struct也是可行的,如果这样做的话,它有助于隔离前2个字节:

[StructLayout( LayoutKind.Sequential )]
public struct TData {
    public byte StartAddress = 0;
    public byte Length = 0;
    public byte[] Data = new byte[ 254 ];
}


如果您尝试使用此功能,我敢肯定您会删除return: MarshalAs并且默认封送处理应能起作用。

09-26 20:46