diff --git a/src/rpi_ws281x/Native/PInvoke.cs b/src/rpi_ws281x/Native/PInvoke.cs index f865429..040fe8b 100644 --- a/src/rpi_ws281x/Native/PInvoke.cs +++ b/src/rpi_ws281x/Native/PInvoke.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; namespace Native @@ -7,17 +8,21 @@ internal class PInvoke { public const int RPI_PWM_CHANNELS = 2; + [SuppressMessage("IDE1006", "IDE1006", Justification = "Native methods have different naming conventions.")] [DllImport("ws2811.so")] - public static extern ws2811_return_t ws2811_init(ref ws2811_t ws2811); + public static extern ws2811_return_t ws2811_init(IntPtr ws2811); + [SuppressMessage("IDE1006", "IDE1006", Justification = "Native methods have different naming conventions.")] [DllImport("ws2811.so")] - public static extern ws2811_return_t ws2811_render(ref ws2811_t ws2811); + public static extern ws2811_return_t ws2811_render(IntPtr ws2811); + [SuppressMessage("IDE1006", "IDE1006", Justification = "Native methods have different naming conventions.")] [DllImport("ws2811.so")] - public static extern ws2811_return_t ws2811_wait(ref ws2811_t ws2811); + public static extern ws2811_return_t ws2811_wait(IntPtr ws2811); + [SuppressMessage("IDE1006", "IDE1006", Justification = "Native methods have different naming conventions.")] [DllImport("ws2811.so")] - public static extern void ws2811_fini(ref ws2811_t ws2811); + public static extern void ws2811_fini(IntPtr ws2811); [DllImport("ws2811.so")] public static extern IntPtr ws2811_get_return_t_str(int state); diff --git a/src/rpi_ws281x/Native/ws2811_t.cs b/src/rpi_ws281x/Native/ws2811_t.cs index 7ba56bf..684da76 100644 --- a/src/rpi_ws281x/Native/ws2811_t.cs +++ b/src/rpi_ws281x/Native/ws2811_t.cs @@ -3,6 +3,7 @@ namespace Native { + [SuppressMessage("IDE1006", "IDE1006", Justification = "Native methods have different naming conventions.")] [StructLayout(LayoutKind.Sequential)] internal struct ws2811_t { @@ -11,7 +12,9 @@ internal struct ws2811_t public IntPtr rpi_hw; public uint freq; public int dmanum; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = PInvoke.RPI_PWM_CHANNELS)] - public ws2811_channel_t[] channel; + /* [MarshalAs(UnmanagedType.ByValArray, SizeConst = PInvoke.RPI_PWM_CHANNELS)] + public ws2811_channel_t[] channel; */ + public ws2811_channel_t channel_1; + public ws2811_channel_t channel_2; } } diff --git a/src/rpi_ws281x/WS281x.cs b/src/rpi_ws281x/WS281x.cs index dc167e6..bd4f3d8 100644 --- a/src/rpi_ws281x/WS281x.cs +++ b/src/rpi_ws281x/WS281x.cs @@ -28,7 +28,9 @@ public WS281x(Settings settings) _ws2811.dmanum = settings.DMAChannel; _ws2811.freq = settings.Frequency; - _ws2811.channel = new ws2811_channel_t[PInvoke.RPI_PWM_CHANNELS]; + //_ws2811.channel = new ws2811_channel_t[PInvoke.RPI_PWM_CHANNELS]; + _ws2811.channel_1 = default; + InitChannel(ref _ws2811.channel_1, settings.Channel); for(int i=0; i<= _ws2811.channel.Length -1; i++) { @@ -40,7 +42,7 @@ public WS281x(Settings settings) Settings = settings; - var initResult = PInvoke.ws2811_init(ref _ws2811); + var initResult = PInvoke.ws2811_init(_ws2811Handle.AddrOfPinnedObject()); if (initResult != ws2811_return_t.WS2811_SUCCESS) { var returnMessage = GetMessageForStatusCode(initResult); @@ -62,11 +64,11 @@ public void Render() if (Settings.Channels[i] != null) { var ledColor = Settings.Channels[i].LEDs.Select(x => x.RGBValue).ToArray(); - Marshal.Copy(ledColor, 0, _ws2811.channel[i].leds, ledColor.Count()); + Marshal.Copy(ledColor, 0, _ws2811.channel_1.leds, ledColor.Count()); } } - var result = PInvoke.ws2811_render(ref _ws2811); + var result = PInvoke.ws2811_render(_ws2811Handle.AddrOfPinnedObject()); if (result != ws2811_return_t.WS2811_SUCCESS) { var returnMessage = GetMessageForStatusCode(result); @@ -93,20 +95,20 @@ public void SetLEDColor(int channelIndex, int ledID, Color color) /// /// Initialize the channel propierties /// - /// Index of the channel tu initialize + /// Channel to initialize /// Settings for the channel - private void InitChannel(int channelIndex, Channel channelSettings) + private void InitChannel(ref ws2811_channel_t channel, Channel channelSettings) { - _ws2811.channel[channelIndex].count = channelSettings.LEDs.Count; - _ws2811.channel[channelIndex].gpionum = channelSettings.GPIOPin; - _ws2811.channel[channelIndex].brightness = channelSettings.Brightness; - _ws2811.channel[channelIndex].invert = Convert.ToInt32(channelSettings.Invert); + channel.count = channelSettings.LEDs.Count; + channel.gpionum = channelSettings.GPIOPin; + channel.brightness = channelSettings.Brightness; + channel.invert = Convert.ToInt32(channelSettings.Invert); if(channelSettings.StripType != StripType.Unknown) { //Strip type is set by the native assembly if not explicitly set. //This type defines the ordering of the colors e. g. RGB or GRB, ... - _ws2811.channel[channelIndex].strip_type = (int)channelSettings.StripType; + channel.strip_type = (int)channelSettings.StripType; } } @@ -138,9 +140,10 @@ protected virtual void Dispose(bool disposing) if(_isDisposingAllowed) { - PInvoke.ws2811_fini(ref _ws2811); - _ws2811Handle.Free(); - + PInvoke.ws2811_fini(_ws2811Handle.AddrOfPinnedObject()); + if (_ws2811Handle.IsAllocated) { + _ws2811Handle.Free(); + } _isDisposingAllowed = false; } @@ -160,8 +163,7 @@ public void Dispose() { // Do not change this code. Put cleanup code in Dispose(bool disposing) above. Dispose(true); - // TODO: uncomment the following line if the finalizer is overridden above. - // GC.SuppressFinalize(this); + GC.SuppressFinalize(this); } #endregion }