USB继电器DLL问题-继续
本文关键字:继续 问题 DLL 继电器 USB | 更新日期: 2023-09-27 18:07:21
这个USB继电器DLL问题下有一个问题[关闭]。cubrr给出了一个很好的可接受的答案。但是当我试图编译程序时,有一个代码给了我一个错误。错误提示
属性'MarshalAs'在此声明类型上无效。它是仅对'field, param, return'声明有效
下面是数据库的代码
using System;
using System.Runtime.InteropServices;
namespace UsbRelay
{
public static class UsbRelayDevice
{
/// <summary>
/// Init the USB Relay Libary
/// </summary>
/// <returns>This function returns 0 on success and -1 on error.</returns>
[DllImport("usb_relay_device.dll", EntryPoint = "usb_relay_init")]
public static extern int Init();
/// <summary>
/// Finalize the USB Relay Libary.
/// This function frees all of the static data associated with
/// USB Relay Libary. It should be called at the end of execution to avoid
/// memory leaks.
/// </summary>
/// <returns>This function returns 0 on success and -1 on error.</returns>
[DllImport("usb_relay_device.dll", EntryPoint = "usb_relay_exit")]
public static extern int Exit();
/// <summary>
/// Enumerate the USB Relay Devices.
/// </summary>
/// <returns></returns>
[DllImport("usb_relay_device.dll", EntryPoint = "usb_relay_device_enumerate")]
public static extern UsbRelayDeviceInfo Enumerate();
/// <summary>
/// Free an enumeration Linked List
/// </summary>
/// <param name="deviceInfo"></param>
[DllImport("usb_relay_device.dll", EntryPoint = "usb_relay_device_free_enumerate")]
public static extern void FreeEnumerate(UsbRelayDeviceInfo deviceInfo);
/// <summary>
/// Open device that serial number is serialNumber
/// </summary>
/// <param name="serialNumber"></param>
/// <param name="stringLength"></param>
/// <returns>This funcation returns a valid handle to the device on success or NULL on failure.</returns>
[DllImport("usb_relay_device.dll", EntryPoint = "usb_relay_device_open_with_serial_number", CharSet = CharSet.Ansi)]
public static extern int OpenWithSerialNumber([MarshalAs(UnmanagedType.LPStr)] string serialNumber, int stringLength);
/// <summary>
/// Open a usb relay device
/// </summary>
/// <param name="deviceInfo"></param>
/// <returns>This funcation returns a valid handle to the device on success or NULL on failure.</returns>
[DllImport("usb_relay_device.dll", EntryPoint = "usb_relay_device_open")]
public static extern int Open(UsbRelayDeviceInfo deviceInfo);
/// <summary>
/// Close a usb relay device
/// </summary>
/// <param name="hHandle"></param>
[DllImport("usb_relay_device.dll", EntryPoint = "usb_relay_device_close")]
public static extern void Close(int hHandle);
/// <summary>
/// open a relay channel on the USB-Relay-Device
/// </summary>
/// <param name="hHandle">Which usb relay device your want to operate</param>
/// <param name="index">Which channel your want to open</param>
/// <returns>0 -- success; 1 -- error; 2 -- index is outnumber the number of the usb relay device</returns>
[DllImport("usb_relay_device.dll", EntryPoint = "usb_relay_device_open_one_relay_channel")]
public static extern int OpenOneRelayChannel(int hHandle, int index);
/// <summary>
/// open all relay channel on the USB-Relay-Device
/// </summary>
/// <param name="hHandle">which usb relay device your want to operate</param>
/// <returns>0 -- success; 1 -- error</returns>
[DllImport("usb_relay_device.dll", EntryPoint = "usb_relay_device_open_all_relay_channel")]
public static extern int OpenAllRelayChannels(int hHandle);
/// <summary>
/// close a relay channel on the USB-Relay-Device
/// </summary>
/// <param name="hHandle">which usb relay device your want to operate</param>
/// <param name="index">which channel your want to close</param>
/// <returns>0 -- success; 1 -- error; 2 -- index is outnumber the number of the usb relay device</returns>
[DllImport("usb_relay_device.dll", EntryPoint = "usb_relay_device_close_one_relay_channel")]
public static extern int CloseOneRelayChannel(int hHandle, int index);
/// <summary>
/// close all relay channel on the USB-Relay-Device
/// </summary>
/// <param name="hHandle">hich usb relay device your want to operate</param>
/// <returns>0 -- success; 1 -- error</returns>
[DllImport("usb_relay_device.dll", EntryPoint = "usb_relay_device_close_all_relay_channel")]
public static extern int CloseAllRelayChannels(int hHandle);
/// <summary>
/// status bit: High --> Low 0000 0000 0000 0000 0000 0000 0000 0000, one bit indicate a relay status.
/// the lowest bit 0 indicate relay one status, 1 -- means open status, 0 -- means closed status.
/// bit 0/1/2/3/4/5/6/7/8 indicate relay 1/2/3/4/5/6/7/8 status
/// </summary>
/// <param name="hHandle"></param>
/// <param name="status"></param>
/// <returns>0 -- success; 1 -- error</returns>
[DllImport("usb_relay_device.dll", EntryPoint = "usb_relay_device_get_status")]
public static extern int GetStatus(int hHandle, ref int status);
}
/// <summary>
/// USB relay board info structure
/// </summary>
[StructLayout(LayoutKind.Sequential, Pack=8)]
public class UsbRelayDeviceInfo
{
[MarshalAs(UnmanagedType.LPStr)] //Error is here
public string SerialNumber { get; set; }
[MarshalAs(UnmanagedType.LPStr)] //Error is here
public string DevicePath { get; set; }
public UsbRelayDeviceType Type { get; set; }
public UsbRelayDeviceInfo Next { get; set; }
}
public enum UsbRelayDeviceType
{
OneChannel = 1,
TwoChannel = 2,
FourChannel = 4,
EightChannel = 8
}
}
此处错误
/// <summary>
/// USB relay board info structure
/// </summary>
[StructLayout(LayoutKind.Sequential, Pack=8)]
public class UsbRelayDeviceInfo
{
[MarshalAs(UnmanagedType.LPStr)] //Error is here
public string SerialNumber { get; set; }
[MarshalAs(UnmanagedType.LPStr)] //Error is here
public string DevicePath { get; set; }
public UsbRelayDeviceType Type { get; set; }
public UsbRelayDeviceInfo Next { get; set; }
}
请帮我解决这个问题
这里是硬件部分的详细信息
这是硬件供应商提供的SDK
错误信息告诉你确切的问题。
属性,甚至是自动属性,都不能被编组。只有普通的旧字段。
改变public string SerialNumber { get; set; }
// ^^^^^^^^^^^^^^
// REMOVE THIS
public string SerialNumber;
我有一个类似的中继器,这篇文章中包含的包装器对我来说效果更好,特别是获取设备序列号:
public enum usb_relay_device_type
{
USB_RELAY_DEVICE_ONE_CHANNEL = 1,
USB_RELAY_DEVICE_TWO_CHANNEL = 2,
USB_RELAY_DEVICE_FOUR_CHANNEL = 4,
USB_RELAY_DEVICE_EIGHT_CHANNEL = 8
}
[StructLayout(LayoutKind.Sequential)]
public struct usb_relay_device_info
{
[MarshalAs(UnmanagedType.LPStr)]
public string serial_number;
public IntPtr device_path { get; set; }
public usb_relay_device_type type { get; set; }
public IntPtr next { get; set; }
}
public class RelayDeviceWrapper
{
[DllImport("usb_relay_device.dll", EntryPoint = "usb_relay_device_enumerate",
CallingConvention = CallingConvention.Cdecl)]
//[return: MarshalAs(UnmanagedType.LPStruct)]
private static extern IntPtr Pusb_relay_device_enumerate();
public static usb_relay_device_info usb_relay_device_enumerate()
{
IntPtr x = RelayDeviceWrapper.Pusb_relay_device_enumerate();
usb_relay_device_info a = (usb_relay_device_info)Marshal.PtrToStructure(x, typeof(usb_relay_device_info));
return a;
}
[DllImport("usb_relay_device.dll", EntryPoint = "usb_relay_init", SetLastError = true,
CharSet = CharSet.Ansi, ExactSpelling = true,
CallingConvention = CallingConvention.Cdecl)]
public static extern int usb_relay_init();
[DllImport("usb_relay_device.dll", EntryPoint = "usb_relay_device_open_with_serial_number", SetLastError = true,
CharSet = CharSet.Ansi, ExactSpelling = true,
CallingConvention = CallingConvention.Cdecl)]
public static extern int usb_relay_device_open_with_serial_number([MarshalAs(UnmanagedType.LPStr)] string serial_number, int len);
[DllImport("usb_relay_device.dll", EntryPoint = "usb_relay_device_close", SetLastError = true,
CharSet = CharSet.Ansi, ExactSpelling = true,
CallingConvention = CallingConvention.Cdecl)]
public static extern void usb_relay_device_close(int hHandle);
[DllImport("usb_relay_device.dll", EntryPoint = "usb_relay_device_open_all_relay_channel", SetLastError = true,
CharSet = CharSet.Ansi, ExactSpelling = true,
CallingConvention = CallingConvention.Cdecl)]
public static extern int usb_relay_device_open_all_relay_channel(int hHandle);
[DllImport("usb_relay_device.dll", EntryPoint = "usb_relay_device_close_all_relay_channel", SetLastError = true,
CharSet = CharSet.Ansi, ExactSpelling = true,
CallingConvention = CallingConvention.Cdecl)]
public static extern int usb_relay_device_close_all_relay_channel(int hHandle);
[DllImport("usb_relay_device.dll", EntryPoint = "usb_relay_device_close_one_relay_channel", SetLastError = true,
CharSet = CharSet.Ansi, ExactSpelling = true,
CallingConvention = CallingConvention.Cdecl)]
public static extern int usb_relay_device_close_one_relay_channel(int hHandle, int index);
[DllImport("usb_relay_device.dll", EntryPoint = "usb_relay_device_open_one_relay_channel", SetLastError = true,
CharSet = CharSet.Ansi, ExactSpelling = true,
CallingConvention = CallingConvention.Cdecl)]
public static extern int usb_relay_device_open_one_relay_channel(int hHandle, int index);
}
然后你可以用下面的代码控制你的继电器:
if (RelayDeviceWrapper.usb_relay_init() != 0)
{
Console.WriteLine("Couldn't initialize!");
return;
}
else { Console.WriteLine("Initialized successfully!"); }
usb_relay_device_info deviceInfo = RelayDeviceWrapper.usb_relay_device_enumerate();
string serial = deviceInfo.serial_number;
int deviceHandle = RelayDeviceWrapper.usb_relay_device_open_with_serial_number(serial, serial.Length);
int openResult = RelayDeviceWrapper.usb_relay_device_open_all_relay_channel(deviceHandle);
if (openResult == 0)
{
Console.WriteLine("No error returned from usb_relay_device_open_one_relay_channel!");
}
else if (openResult == 1)
{
Console.WriteLine("Got error from OpenOneRelayChannel!");
return;
}
RelayDeviceWrapper.usb_relay_device_close(deviceHandle);