From a84bd89b6f2032e9995ed384659d484122eecb36 Mon Sep 17 00:00:00 2001 From: jonnew Date: Tue, 24 Jun 2025 13:38:58 -0400 Subject: [PATCH 1/5] Upgrade clroni to .net8.0 - Take advantage of the API improvements afforded by this framework - Follow best practices for P/Invoke: https://learn.microsoft.com/en-us/dotnet/standard/native-interop/best-practices - DllImport -> LibraryImport - Use [In] and [Out] attributes on array parameters and dont use StringBuilder --- api/clroni/clroni-repl/Repl.cs | 23 ++--- api/clroni/clroni-repl/clroni-repl.csproj | 7 +- api/clroni/clroni/Context.cs | 12 +-- api/clroni/clroni/ContextHandle.cs | 7 +- api/clroni/clroni/Frame.cs | 5 - api/clroni/clroni/ONIException.cs | 10 +- api/clroni/clroni/clroni.csproj | 12 +-- api/clroni/clroni/oni.cs | 108 ++++++++++++---------- api/clroni/clroni/onix.cs | 10 +- 9 files changed, 92 insertions(+), 102 deletions(-) diff --git a/api/clroni/clroni-repl/Repl.cs b/api/clroni/clroni-repl/Repl.cs index 818b03c..14386da 100644 --- a/api/clroni/clroni-repl/Repl.cs +++ b/api/clroni/clroni-repl/Repl.cs @@ -1,29 +1,19 @@ using oni; -using System; using System.Runtime.InteropServices; -using System.Threading; using CommandLine; -using System.Linq; using CommandLine.Text; namespace ClrOniRepl { - class DataProcessor + class DataProcessor(Context context, bool display = false, ulong displayEvery = 1000) { - private readonly Context context; + private readonly Context context = context; public volatile bool Quit = false; - public bool Display { get; set; } + public bool Display { get; set; } = display; - public ulong DisplayEvery { get; set; } - - public DataProcessor(Context context, bool display = false, ulong displayEvery = 1000) - { - this.context = context; - Display = display; - DisplayEvery = displayEvery; - } + public ulong DisplayEvery { get; set; } = displayEvery; public void CaptureData() { @@ -219,7 +209,12 @@ static void Main(string[] args) break; case 'x': + processor.Quit = true; + procThread.Join(200); ctx.Refresh(); + Console.Write(Helpers.DeviceTableString(ctx)); + ctx.Start(true); + procThread.Start(); break; default: diff --git a/api/clroni/clroni-repl/clroni-repl.csproj b/api/clroni/clroni-repl/clroni-repl.csproj index b96bbb1..68cf03b 100644 --- a/api/clroni/clroni-repl/clroni-repl.csproj +++ b/api/clroni/clroni-repl/clroni-repl.csproj @@ -1,10 +1,11 @@ - + - ONI RELLPL (RCRLLR)(CLR) + ONI REPL Test application for clroni. ONI Open Ephys - net472 + net8.0 + enable 1.2.2 MIT Copyright © Open Ephys, Inc. diff --git a/api/clroni/clroni/Context.cs b/api/clroni/clroni/Context.cs index fdccd23..170f832 100644 --- a/api/clroni/clroni/Context.cs +++ b/api/clroni/clroni/Context.cs @@ -2,8 +2,6 @@ using System.Collections; using System.Collections.Generic; using System.Runtime.InteropServices; -using System.Security.Permissions; -using System.Text; namespace oni { @@ -183,17 +181,20 @@ private int GetIntOption(int option, bool drv_opt = false) // String GetOption private string GetStringOption(int option, bool drv_opt = false) { + const int BufferSize = 1000; + var sz = Marshal.AllocHGlobal(IntPtr.Size); if (IntPtr.Size == 4) { - Marshal.WriteInt32(sz, 1000); + Marshal.WriteInt32(sz, BufferSize); } else { - Marshal.WriteInt64(sz, 1000); + Marshal.WriteInt64(sz, BufferSize); } - var str = new StringBuilder(1000); + //var str = new StringBuilder(1000); + var str = new char[BufferSize]; int rc; if (!drv_opt) @@ -555,7 +556,6 @@ public void Dispose() /// by IDisposable. /// /// - [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)] protected virtual void Dispose(bool disposing) { diff --git a/api/clroni/clroni/ContextHandle.cs b/api/clroni/clroni/ContextHandle.cs index 91978aa..0796e34 100644 --- a/api/clroni/clroni/ContextHandle.cs +++ b/api/clroni/clroni/ContextHandle.cs @@ -1,16 +1,11 @@ using Microsoft.Win32.SafeHandles; -using System.Runtime.ConstrainedExecution; -using System.Security.Permissions; namespace oni { - [SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode = true)] - [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)] - internal unsafe class ContextHandle : SafeHandleZeroOrMinusOneIsInvalid + internal class ContextHandle : SafeHandleZeroOrMinusOneIsInvalid { internal ContextHandle() : base(true) { } - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] protected override bool ReleaseHandle() { return NativeMethods.oni_destroy_ctx(handle) == 0; diff --git a/api/clroni/clroni/Frame.cs b/api/clroni/clroni/Frame.cs index a493504..73ff291 100644 --- a/api/clroni/clroni/Frame.cs +++ b/api/clroni/clroni/Frame.cs @@ -1,8 +1,6 @@ using Microsoft.Win32.SafeHandles; using System; -using System.Runtime.ConstrainedExecution; using System.Runtime.InteropServices; -using System.Security.Permissions; namespace oni { @@ -10,8 +8,6 @@ namespace oni /// Managed wrapper for an ONI-compliant data frame implementation. Produced by calls /// to . /// - [SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode = true)] - [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)] public unsafe class Frame : SafeHandleZeroOrMinusOneIsInvalid { @@ -36,7 +32,6 @@ internal Frame(IntPtr handle) /// /// True if the handle is released successfully (always the case /// in this implementation) - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] protected override bool ReleaseHandle() { GC.RemoveMemoryPressure(((frame_t*)handle.ToPointer())->data_sz); diff --git a/api/clroni/clroni/ONIException.cs b/api/clroni/clroni/ONIException.cs index a5cd4f2..718693f 100644 --- a/api/clroni/clroni/ONIException.cs +++ b/api/clroni/clroni/ONIException.cs @@ -1,6 +1,5 @@ using System; using System.Runtime.InteropServices; -using System.Runtime.Serialization; namespace oni { @@ -15,10 +14,13 @@ public class ONIException : Exception /// public readonly int Number; + /// + /// Initializes a new + /// protected ONIException() { } /// - /// Initializes a new + /// Initializes a new /// /// The error code returned by the native ONI API. internal ONIException(int errnum) @@ -31,9 +33,5 @@ internal ONIException(int errnum) /// public override string Message => Marshal.PtrToStringAnsi(NativeMethods.oni_error_str(Number)); - - protected ONIException(SerializationInfo info, StreamingContext context) - : base(info, context) - { } } } diff --git a/api/clroni/clroni/clroni.csproj b/api/clroni/clroni/clroni.csproj index f05bf3c..8e623f4 100644 --- a/api/clroni/clroni/clroni.csproj +++ b/api/clroni/clroni/clroni.csproj @@ -1,16 +1,12 @@ - + CLR bindings for liboni CLR bindings to liboni, an ONI compliant API for data acquisition. ONI Open Ephys ONIX - net472 - true -<<<<<<< riffa-hardreset - 6.2.0 -======= - 6.1.3 ->>>>>>> main + net8.0 + false + 6.3.0-dev1 Jon Newman Open Ephys, Inc. ©Open Ephys, Inc. diff --git a/api/clroni/clroni/oni.cs b/api/clroni/clroni/oni.cs index fabfec4..2f60052 100644 --- a/api/clroni/clroni/oni.cs +++ b/api/clroni/clroni/oni.cs @@ -1,8 +1,7 @@ using System; -using System.Runtime.ConstrainedExecution; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Security; -using System.Text; namespace oni { @@ -20,11 +19,8 @@ public static partial class NativeMethods /// public static readonly Version LibraryVersion; - private const CallingConvention CCCdecl = CallingConvention.Cdecl; + const string LibraryName = "liboni"; - private const string LibraryName = "liboni"; - - // The static constructor prepares static readonly fields static NativeMethods() { // Set once LibraryVersion to version() @@ -47,60 +43,69 @@ private static NotSupportedException VersionNotSupported(string methodName, stri requiredVersion)); } + [LibraryImport(LibraryName)] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + internal static partial void oni_version(out int major, out int minor, out int patch); - - - [DllImport(LibraryName, CallingConvention = CCCdecl)] - internal static extern void oni_version(out int major, out int minor, out int patch); - - [DllImport(LibraryName, CallingConvention = CCCdecl, CharSet = CharSet.Ansi)] + [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] internal static extern ContextHandle oni_create_ctx(string driver_name); - [DllImport(LibraryName, CallingConvention = CCCdecl)] - internal static extern int oni_init_ctx(ContextHandle ctx, int host_idx); + [LibraryImport(LibraryName)] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + internal static partial int oni_init_ctx(ContextHandle ctx, int host_idx); - [DllImport(LibraryName, CallingConvention = CCCdecl)] - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] - internal static extern int oni_destroy_ctx(IntPtr ctx); + [LibraryImport(LibraryName)] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + internal static partial int oni_destroy_ctx(IntPtr ctx); - [DllImport(LibraryName, CallingConvention = CCCdecl)] - internal static extern int oni_get_opt(ContextHandle ctx, int option, IntPtr val, IntPtr size); + [LibraryImport(LibraryName)] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + internal static partial int oni_get_opt(ContextHandle ctx, int option, IntPtr val, IntPtr size); - [DllImport(LibraryName, CallingConvention = CCCdecl)] - internal static extern int oni_get_opt(ContextHandle ctx, int option, StringBuilder val, IntPtr size); + [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern int oni_get_opt(ContextHandle ctx, int option, [Out] char[] val, IntPtr size); - [DllImport(LibraryName, CallingConvention = CCCdecl)] - internal static extern int oni_set_opt(ContextHandle ctx, int option, IntPtr val, int size); + [LibraryImport(LibraryName)] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + internal static partial int oni_set_opt(ContextHandle ctx, int option, IntPtr val, int size); - [DllImport(LibraryName, CallingConvention = CCCdecl)] - internal static extern int oni_set_opt(ContextHandle ctx, int option, string val, int size); + [LibraryImport(LibraryName, StringMarshalling = StringMarshalling.Utf8)] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + internal static partial int oni_set_opt(ContextHandle ctx, int option, string val, int size); - [DllImport(LibraryName, CallingConvention = CCCdecl)] - internal static extern IntPtr oni_get_driver_info(ContextHandle ctx); + [LibraryImport(LibraryName)] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + internal static partial IntPtr oni_get_driver_info(ContextHandle ctx); - [DllImport(LibraryName, CallingConvention = CCCdecl)] - internal static extern int oni_get_driver_opt(ContextHandle ctx, int option, IntPtr val, IntPtr size); + [LibraryImport(LibraryName)] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + internal static partial int oni_get_driver_opt(ContextHandle ctx, int option, IntPtr val, IntPtr size); - [DllImport(LibraryName, CallingConvention = CCCdecl)] - internal static extern int oni_get_driver_opt(ContextHandle ctx, int option, StringBuilder val, IntPtr size); + [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern int oni_get_driver_opt(ContextHandle ctx, int option, [Out] char[] val, IntPtr size); - [DllImport(LibraryName, CallingConvention = CCCdecl)] - internal static extern int oni_set_driver_opt(ContextHandle ctx, int option, IntPtr val, int size); + [LibraryImport(LibraryName)] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + internal static partial int oni_set_driver_opt(ContextHandle ctx, int option, IntPtr val, int size); - [DllImport(LibraryName, CallingConvention = CCCdecl)] - internal static extern int oni_set_driver_opt(ContextHandle ctx, int option, string val, int size); + [LibraryImport(LibraryName, StringMarshalling = StringMarshalling.Utf8)] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + internal static partial int oni_set_driver_opt(ContextHandle ctx, int option, string val, int size); - [DllImport(LibraryName, CallingConvention = CCCdecl)] - internal static extern int oni_read_reg(ContextHandle ctx, uint dev_idx, uint addr, IntPtr val); + [LibraryImport(LibraryName)] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + internal static partial int oni_read_reg(ContextHandle ctx, uint dev_idx, uint addr, IntPtr val); - [DllImport(LibraryName, CallingConvention = CCCdecl)] - internal static extern int oni_write_reg(ContextHandle ctx, uint dev_idx, uint addr, uint val); + [LibraryImport(LibraryName)] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + internal static partial int oni_write_reg(ContextHandle ctx, uint dev_idx, uint addr, uint val); //[DllImport(LibraryName, CallingConvention = CCCdecl, SetLastError = true)] //internal static extern int oni_read_frame(ContextHandle ctx, out Frame frame); - [DllImport(LibraryName, CallingConvention = CCCdecl, SetLastError = true)] - internal static extern int oni_read_frame(ContextHandle ctx, out IntPtr frame); + [LibraryImport(LibraryName, SetLastError = true)] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + internal static partial int oni_read_frame(ContextHandle ctx, out IntPtr frame); //[DllImport(LibraryName, CallingConvention = CCCdecl, SetLastError = true)] //internal static extern int oni_create_frame(ContextHandle ctx, out Frame frame, uint dev_idx, IntPtr data, uint data_sz); @@ -108,17 +113,20 @@ private static NotSupportedException VersionNotSupported(string methodName, stri //[DllImport(LibraryName, CallingConvention = CCCdecl, SetLastError = true)] //internal static extern int oni_write_frame(ContextHandle ctx, Frame frame); - [DllImport(LibraryName, CallingConvention = CCCdecl, SetLastError = true)] - internal static extern int oni_create_frame(ContextHandle ctx, out IntPtr frame, uint dev_idx, IntPtr data, uint data_sz); + [LibraryImport(LibraryName, SetLastError = true)] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + internal static partial int oni_create_frame(ContextHandle ctx, out IntPtr frame, uint dev_idx, IntPtr data, uint data_sz); - [DllImport(LibraryName, CallingConvention = CCCdecl, SetLastError = true)] - internal static extern int oni_write_frame(ContextHandle ctx, IntPtr frame); + [LibraryImport(LibraryName, SetLastError = true)] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + internal static partial int oni_write_frame(ContextHandle ctx, IntPtr frame); - [DllImport(LibraryName, CallingConvention = CCCdecl)] - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] - internal static extern void oni_destroy_frame(IntPtr frame); + [LibraryImport(LibraryName)] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + internal static partial void oni_destroy_frame(IntPtr frame); - [DllImport(LibraryName, CallingConvention = CCCdecl)] - internal static extern IntPtr oni_error_str(int err); + [LibraryImport(LibraryName)] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + internal static partial IntPtr oni_error_str(int err); } } diff --git a/api/clroni/clroni/onix.cs b/api/clroni/clroni/onix.cs index f0677cc..99c7bc6 100644 --- a/api/clroni/clroni/onix.cs +++ b/api/clroni/clroni/onix.cs @@ -106,10 +106,12 @@ public Hub GetHub(uint device_address) [SuppressUnmanagedCodeSecurity] // NB: Call into native code without incurring the performance loss of a run-time security check when doing so public static partial class NativeMethods { - [DllImport(LibraryName, CallingConvention = CCCdecl)] - internal static extern IntPtr onix_device_str(int id); + [LibraryImport(LibraryName)] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(System.Runtime.CompilerServices.CallConvCdecl) })] + internal static partial IntPtr onix_device_str(int id); - [DllImport(LibraryName, CallingConvention = CCCdecl)] - internal static extern IntPtr onix_hub_str(int id); + [LibraryImport(LibraryName)] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(System.Runtime.CompilerServices.CallConvCdecl) })] + internal static partial IntPtr onix_hub_str(int id); } } From 37262e16577a1b682cf545a1318ff679ea9ad608 Mon Sep 17 00:00:00 2001 From: Aaron Cuevas Lopez <1830303+aacuevas@users.noreply.github.com> Date: Tue, 30 Sep 2025 05:45:53 +0200 Subject: [PATCH 2/5] Enable multitarget build --- api/clroni/clroni/Context.cs | 15 +++++- api/clroni/clroni/ContextHandle.cs | 12 ++++- api/clroni/clroni/Frame.cs | 15 ++++++ api/clroni/clroni/ONIException.cs | 9 ++++ api/clroni/clroni/clroni.csproj | 2 +- api/clroni/clroni/oni.cs | 86 +++++++++++++++++++++++++++++- api/clroni/clroni/onix.cs | 8 +++ 7 files changed, 143 insertions(+), 4 deletions(-) diff --git a/api/clroni/clroni/Context.cs b/api/clroni/clroni/Context.cs index 170f832..2e51038 100644 --- a/api/clroni/clroni/Context.cs +++ b/api/clroni/clroni/Context.cs @@ -2,6 +2,10 @@ using System.Collections; using System.Collections.Generic; using System.Runtime.InteropServices; +#if !NET7_0_OR_GREATER +using System.Security.Permissions; +using System.Text; +#endif namespace oni { @@ -193,8 +197,12 @@ private string GetStringOption(int option, bool drv_opt = false) Marshal.WriteInt64(sz, BufferSize); } - //var str = new StringBuilder(1000); + +#if NET7_0_OR_GREATER var str = new char[BufferSize]; +#else + var str = new StringBuilder(BufferSize); +#endif int rc; if (!drv_opt) @@ -556,7 +564,12 @@ public void Dispose() /// by IDisposable. /// /// +#if NET7_0_OR_GREATER + protected virtual void Dispose(bool disposing) +#else + [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)] protected virtual void Dispose(bool disposing) +#endif { if (ctx != null && !ctx.IsInvalid) diff --git a/api/clroni/clroni/ContextHandle.cs b/api/clroni/clroni/ContextHandle.cs index 0796e34..eb0773c 100644 --- a/api/clroni/clroni/ContextHandle.cs +++ b/api/clroni/clroni/ContextHandle.cs @@ -1,10 +1,20 @@ using Microsoft.Win32.SafeHandles; +#if !NET7_0_OR_GREATER +using System.Runtime.ConstrainedExecution; +using System.Security.Permissions; +#endif namespace oni { +#if NET7_0_OR_GREATER internal class ContextHandle : SafeHandleZeroOrMinusOneIsInvalid +#else + [SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode = true)] + [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)] + internal unsafe class ContextHandle : SafeHandleZeroOrMinusOneIsInvalid +#endif { - internal ContextHandle() : base(true) { } + public ContextHandle() : base(true) { } protected override bool ReleaseHandle() { diff --git a/api/clroni/clroni/Frame.cs b/api/clroni/clroni/Frame.cs index 73ff291..e1ba2e9 100644 --- a/api/clroni/clroni/Frame.cs +++ b/api/clroni/clroni/Frame.cs @@ -1,6 +1,10 @@ using Microsoft.Win32.SafeHandles; using System; using System.Runtime.InteropServices; +#if !NET7_0_OR_GREATER +using System.Runtime.ConstrainedExecution; +using System.Security.Permissions; +#endif namespace oni { @@ -8,7 +12,13 @@ namespace oni /// Managed wrapper for an ONI-compliant data frame implementation. Produced by calls /// to . /// +#if NET7_0_OR_GREATER public unsafe class Frame : SafeHandleZeroOrMinusOneIsInvalid +#else + [SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode = true)] + [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)] + public unsafe class Frame : SafeHandleZeroOrMinusOneIsInvalid +#endif { [StructLayout(LayoutKind.Sequential)] @@ -32,7 +42,12 @@ internal Frame(IntPtr handle) /// /// True if the handle is released successfully (always the case /// in this implementation) +#if NET7_0_OR_GREATER + protected override bool ReleaseHandle() +#else + [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] protected override bool ReleaseHandle() +#endif { GC.RemoveMemoryPressure(((frame_t*)handle.ToPointer())->data_sz); NativeMethods.oni_destroy_frame(handle); diff --git a/api/clroni/clroni/ONIException.cs b/api/clroni/clroni/ONIException.cs index 718693f..f69c70a 100644 --- a/api/clroni/clroni/ONIException.cs +++ b/api/clroni/clroni/ONIException.cs @@ -1,5 +1,8 @@ using System; using System.Runtime.InteropServices; +#if !NET7_0_OR_GREATER +using System.Runtime.Serialization; +#endif namespace oni { @@ -33,5 +36,11 @@ internal ONIException(int errnum) /// public override string Message => Marshal.PtrToStringAnsi(NativeMethods.oni_error_str(Number)); + +#if !NET7_0_OR_GREATER + protected ONIException(SerializationInfo info, StreamingContext context) + : base(info, context) + { } +#endif } } diff --git a/api/clroni/clroni/clroni.csproj b/api/clroni/clroni/clroni.csproj index 8e623f4..03dcbcb 100644 --- a/api/clroni/clroni/clroni.csproj +++ b/api/clroni/clroni/clroni.csproj @@ -4,7 +4,7 @@ CLR bindings for liboni CLR bindings to liboni, an ONI compliant API for data acquisition. ONI Open Ephys ONIX - net8.0 + net472;netstandard2.0;net8.0 false 6.3.0-dev1 Jon Newman diff --git a/api/clroni/clroni/oni.cs b/api/clroni/clroni/oni.cs index 2f60052..82b316a 100644 --- a/api/clroni/clroni/oni.cs +++ b/api/clroni/clroni/oni.cs @@ -1,7 +1,13 @@ using System; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Security; +using System.Text; + +#if NET7_0_OR_GREATER +using System.Runtime.CompilerServices; +#else +using System.Runtime.ConstrainedExecution; +#endif namespace oni { @@ -21,6 +27,10 @@ public static partial class NativeMethods const string LibraryName = "liboni"; +#if !NET7_0_OR_GREATER + private const CallingConvention CCCdecl = CallingConvention.Cdecl; +#endif + static NativeMethods() { // Set once LibraryVersion to version() @@ -43,6 +53,8 @@ private static NotSupportedException VersionNotSupported(string methodName, stri requiredVersion)); } +#if NET7_0_OR_GREATER + [LibraryImport(LibraryName)] [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] internal static partial void oni_version(out int major, out int minor, out int patch); @@ -128,5 +140,77 @@ private static NotSupportedException VersionNotSupported(string methodName, stri [LibraryImport(LibraryName)] [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] internal static partial IntPtr oni_error_str(int err); +#else + [DllImport(LibraryName, CallingConvention = CCCdecl)] + internal static extern void oni_version(out int major, out int minor, out int patch); + + [DllImport(LibraryName, CallingConvention = CCCdecl, CharSet = CharSet.Ansi)] + internal static extern ContextHandle oni_create_ctx(string driver_name); + + [DllImport(LibraryName, CallingConvention = CCCdecl)] + internal static extern int oni_init_ctx(ContextHandle ctx, int host_idx); + + [DllImport(LibraryName, CallingConvention = CCCdecl)] + [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] + internal static extern int oni_destroy_ctx(IntPtr ctx); + + [DllImport(LibraryName, CallingConvention = CCCdecl)] + internal static extern int oni_get_opt(ContextHandle ctx, int option, IntPtr val, IntPtr size); + + [DllImport(LibraryName, CallingConvention = CCCdecl)] + internal static extern int oni_get_opt(ContextHandle ctx, int option, StringBuilder val, IntPtr size); + + [DllImport(LibraryName, CallingConvention = CCCdecl)] + internal static extern int oni_set_opt(ContextHandle ctx, int option, IntPtr val, int size); + + [DllImport(LibraryName, CallingConvention = CCCdecl)] + internal static extern int oni_set_opt(ContextHandle ctx, int option, string val, int size); + + [DllImport(LibraryName, CallingConvention = CCCdecl)] + internal static extern IntPtr oni_get_driver_info(ContextHandle ctx); + + [DllImport(LibraryName, CallingConvention = CCCdecl)] + internal static extern int oni_get_driver_opt(ContextHandle ctx, int option, IntPtr val, IntPtr size); + + [DllImport(LibraryName, CallingConvention = CCCdecl)] + internal static extern int oni_get_driver_opt(ContextHandle ctx, int option, StringBuilder val, IntPtr size); + + [DllImport(LibraryName, CallingConvention = CCCdecl)] + internal static extern int oni_set_driver_opt(ContextHandle ctx, int option, IntPtr val, int size); + + [DllImport(LibraryName, CallingConvention = CCCdecl)] + internal static extern int oni_set_driver_opt(ContextHandle ctx, int option, string val, int size); + + [DllImport(LibraryName, CallingConvention = CCCdecl)] + internal static extern int oni_read_reg(ContextHandle ctx, uint dev_idx, uint addr, IntPtr val); + + [DllImport(LibraryName, CallingConvention = CCCdecl)] + internal static extern int oni_write_reg(ContextHandle ctx, uint dev_idx, uint addr, uint val); + + //[DllImport(LibraryName, CallingConvention = CCCdecl, SetLastError = true)] + //internal static extern int oni_read_frame(ContextHandle ctx, out Frame frame); + + [DllImport(LibraryName, CallingConvention = CCCdecl, SetLastError = true)] + internal static extern int oni_read_frame(ContextHandle ctx, out IntPtr frame); + + //[DllImport(LibraryName, CallingConvention = CCCdecl, SetLastError = true)] + //internal static extern int oni_create_frame(ContextHandle ctx, out Frame frame, uint dev_idx, IntPtr data, uint data_sz); + + //[DllImport(LibraryName, CallingConvention = CCCdecl, SetLastError = true)] + //internal static extern int oni_write_frame(ContextHandle ctx, Frame frame); + + [DllImport(LibraryName, CallingConvention = CCCdecl, SetLastError = true)] + internal static extern int oni_create_frame(ContextHandle ctx, out IntPtr frame, uint dev_idx, IntPtr data, uint data_sz); + + [DllImport(LibraryName, CallingConvention = CCCdecl, SetLastError = true)] + internal static extern int oni_write_frame(ContextHandle ctx, IntPtr frame); + + [DllImport(LibraryName, CallingConvention = CCCdecl)] + [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] + internal static extern void oni_destroy_frame(IntPtr frame); + + [DllImport(LibraryName, CallingConvention = CCCdecl)] + internal static extern IntPtr oni_error_str(int err); +#endif } } diff --git a/api/clroni/clroni/onix.cs b/api/clroni/clroni/onix.cs index 99c7bc6..89ba6ec 100644 --- a/api/clroni/clroni/onix.cs +++ b/api/clroni/clroni/onix.cs @@ -106,6 +106,7 @@ public Hub GetHub(uint device_address) [SuppressUnmanagedCodeSecurity] // NB: Call into native code without incurring the performance loss of a run-time security check when doing so public static partial class NativeMethods { +#if NET7_0_OR_GREATER [LibraryImport(LibraryName)] [UnmanagedCallConv(CallConvs = new Type[] { typeof(System.Runtime.CompilerServices.CallConvCdecl) })] internal static partial IntPtr onix_device_str(int id); @@ -113,5 +114,12 @@ public static partial class NativeMethods [LibraryImport(LibraryName)] [UnmanagedCallConv(CallConvs = new Type[] { typeof(System.Runtime.CompilerServices.CallConvCdecl) })] internal static partial IntPtr onix_hub_str(int id); +#else + [DllImport(LibraryName, CallingConvention = CCCdecl)] + internal static extern IntPtr onix_device_str(int id); + + [DllImport(LibraryName, CallingConvention = CCCdecl)] + internal static extern IntPtr onix_hub_str(int id); +#endif } } From c49ff99b346c1e7d10159d0b389a6a0117a22b52 Mon Sep 17 00:00:00 2001 From: Aaron Cuevas Lopez <1830303+aacuevas@users.noreply.github.com> Date: Tue, 30 Sep 2025 15:31:00 +0200 Subject: [PATCH 3/5] Separate native method files for cleaner project --- api/clroni/clroni/Context.cs | 3 +- api/clroni/clroni/ContextHandle.cs | 3 +- api/clroni/clroni/Frame.cs | 3 +- api/clroni/clroni/ONIException.cs | 3 +- api/clroni/clroni/clroni.csproj | 12 +- api/clroni/clroni/oni.cs | 216 ----------------------------- 6 files changed, 15 insertions(+), 225 deletions(-) delete mode 100644 api/clroni/clroni/oni.cs diff --git a/api/clroni/clroni/Context.cs b/api/clroni/clroni/Context.cs index 2e51038..89a1f56 100644 --- a/api/clroni/clroni/Context.cs +++ b/api/clroni/clroni/Context.cs @@ -2,10 +2,9 @@ using System.Collections; using System.Collections.Generic; using System.Runtime.InteropServices; -#if !NET7_0_OR_GREATER using System.Security.Permissions; using System.Text; -#endif + namespace oni { diff --git a/api/clroni/clroni/ContextHandle.cs b/api/clroni/clroni/ContextHandle.cs index eb0773c..49a16d5 100644 --- a/api/clroni/clroni/ContextHandle.cs +++ b/api/clroni/clroni/ContextHandle.cs @@ -1,8 +1,7 @@ using Microsoft.Win32.SafeHandles; -#if !NET7_0_OR_GREATER using System.Runtime.ConstrainedExecution; using System.Security.Permissions; -#endif + namespace oni { diff --git a/api/clroni/clroni/Frame.cs b/api/clroni/clroni/Frame.cs index e1ba2e9..d83c5f3 100644 --- a/api/clroni/clroni/Frame.cs +++ b/api/clroni/clroni/Frame.cs @@ -1,10 +1,9 @@ using Microsoft.Win32.SafeHandles; using System; using System.Runtime.InteropServices; -#if !NET7_0_OR_GREATER using System.Runtime.ConstrainedExecution; using System.Security.Permissions; -#endif + namespace oni { diff --git a/api/clroni/clroni/ONIException.cs b/api/clroni/clroni/ONIException.cs index f69c70a..fde5fc1 100644 --- a/api/clroni/clroni/ONIException.cs +++ b/api/clroni/clroni/ONIException.cs @@ -1,8 +1,7 @@ using System; using System.Runtime.InteropServices; -#if !NET7_0_OR_GREATER using System.Runtime.Serialization; -#endif + namespace oni { diff --git a/api/clroni/clroni/clroni.csproj b/api/clroni/clroni/clroni.csproj index 03dcbcb..49715de 100644 --- a/api/clroni/clroni/clroni.csproj +++ b/api/clroni/clroni/clroni.csproj @@ -4,7 +4,7 @@ CLR bindings for liboni CLR bindings to liboni, an ONI compliant API for data acquisition. ONI Open Ephys ONIX - net472;netstandard2.0;net8.0 + net8.0;net472;netstandard2.0 false 6.3.0-dev1 Jon Newman @@ -40,6 +40,16 @@ + + + + + + + + + + diff --git a/api/clroni/clroni/oni.cs b/api/clroni/clroni/oni.cs deleted file mode 100644 index 82b316a..0000000 --- a/api/clroni/clroni/oni.cs +++ /dev/null @@ -1,216 +0,0 @@ -using System; -using System.Runtime.InteropServices; -using System.Security; -using System.Text; - -#if NET7_0_OR_GREATER -using System.Runtime.CompilerServices; -#else -using System.Runtime.ConstrainedExecution; -#endif - -namespace oni -{ - /// - /// Common language runtime bindings to liboni C library. The functionality - /// these bindings is exposed through higher-order types: , - /// , , , - /// and . - /// - [SuppressUnmanagedCodeSecurity] // NB: Call into native code without incurring the performance loss of a run-time security check when doing so - public static partial class NativeMethods - { - /// - /// Semantic version of this library. - /// - public static readonly Version LibraryVersion; - - const string LibraryName = "liboni"; - -#if !NET7_0_OR_GREATER - private const CallingConvention CCCdecl = CallingConvention.Cdecl; -#endif - - static NativeMethods() - { - // Set once LibraryVersion to version() - oni_version(out int major, out int minor, out int patch); - LibraryVersion = new Version(major, minor, patch); - - // Make sure it is supported - if (major < 4) - { - throw VersionNotSupported(null, ">= v4.0.0"); - } - } - - private static NotSupportedException VersionNotSupported(string methodName, string requiredVersion) - { - return new NotSupportedException( - string.Format( - "{0}liboni version not supported. Required version {1}", - methodName == null ? string.Empty : methodName + ": ", - requiredVersion)); - } - -#if NET7_0_OR_GREATER - - [LibraryImport(LibraryName)] - [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] - internal static partial void oni_version(out int major, out int minor, out int patch); - - [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static extern ContextHandle oni_create_ctx(string driver_name); - - [LibraryImport(LibraryName)] - [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] - internal static partial int oni_init_ctx(ContextHandle ctx, int host_idx); - - [LibraryImport(LibraryName)] - [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] - internal static partial int oni_destroy_ctx(IntPtr ctx); - - [LibraryImport(LibraryName)] - [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] - internal static partial int oni_get_opt(ContextHandle ctx, int option, IntPtr val, IntPtr size); - - [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static extern int oni_get_opt(ContextHandle ctx, int option, [Out] char[] val, IntPtr size); - - [LibraryImport(LibraryName)] - [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] - internal static partial int oni_set_opt(ContextHandle ctx, int option, IntPtr val, int size); - - [LibraryImport(LibraryName, StringMarshalling = StringMarshalling.Utf8)] - [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] - internal static partial int oni_set_opt(ContextHandle ctx, int option, string val, int size); - - [LibraryImport(LibraryName)] - [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] - internal static partial IntPtr oni_get_driver_info(ContextHandle ctx); - - [LibraryImport(LibraryName)] - [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] - internal static partial int oni_get_driver_opt(ContextHandle ctx, int option, IntPtr val, IntPtr size); - - [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static extern int oni_get_driver_opt(ContextHandle ctx, int option, [Out] char[] val, IntPtr size); - - [LibraryImport(LibraryName)] - [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] - internal static partial int oni_set_driver_opt(ContextHandle ctx, int option, IntPtr val, int size); - - [LibraryImport(LibraryName, StringMarshalling = StringMarshalling.Utf8)] - [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] - internal static partial int oni_set_driver_opt(ContextHandle ctx, int option, string val, int size); - - [LibraryImport(LibraryName)] - [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] - internal static partial int oni_read_reg(ContextHandle ctx, uint dev_idx, uint addr, IntPtr val); - - [LibraryImport(LibraryName)] - [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] - internal static partial int oni_write_reg(ContextHandle ctx, uint dev_idx, uint addr, uint val); - - //[DllImport(LibraryName, CallingConvention = CCCdecl, SetLastError = true)] - //internal static extern int oni_read_frame(ContextHandle ctx, out Frame frame); - - [LibraryImport(LibraryName, SetLastError = true)] - [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] - internal static partial int oni_read_frame(ContextHandle ctx, out IntPtr frame); - - //[DllImport(LibraryName, CallingConvention = CCCdecl, SetLastError = true)] - //internal static extern int oni_create_frame(ContextHandle ctx, out Frame frame, uint dev_idx, IntPtr data, uint data_sz); - - //[DllImport(LibraryName, CallingConvention = CCCdecl, SetLastError = true)] - //internal static extern int oni_write_frame(ContextHandle ctx, Frame frame); - - [LibraryImport(LibraryName, SetLastError = true)] - [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] - internal static partial int oni_create_frame(ContextHandle ctx, out IntPtr frame, uint dev_idx, IntPtr data, uint data_sz); - - [LibraryImport(LibraryName, SetLastError = true)] - [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] - internal static partial int oni_write_frame(ContextHandle ctx, IntPtr frame); - - [LibraryImport(LibraryName)] - [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] - internal static partial void oni_destroy_frame(IntPtr frame); - - [LibraryImport(LibraryName)] - [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] - internal static partial IntPtr oni_error_str(int err); -#else - [DllImport(LibraryName, CallingConvention = CCCdecl)] - internal static extern void oni_version(out int major, out int minor, out int patch); - - [DllImport(LibraryName, CallingConvention = CCCdecl, CharSet = CharSet.Ansi)] - internal static extern ContextHandle oni_create_ctx(string driver_name); - - [DllImport(LibraryName, CallingConvention = CCCdecl)] - internal static extern int oni_init_ctx(ContextHandle ctx, int host_idx); - - [DllImport(LibraryName, CallingConvention = CCCdecl)] - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] - internal static extern int oni_destroy_ctx(IntPtr ctx); - - [DllImport(LibraryName, CallingConvention = CCCdecl)] - internal static extern int oni_get_opt(ContextHandle ctx, int option, IntPtr val, IntPtr size); - - [DllImport(LibraryName, CallingConvention = CCCdecl)] - internal static extern int oni_get_opt(ContextHandle ctx, int option, StringBuilder val, IntPtr size); - - [DllImport(LibraryName, CallingConvention = CCCdecl)] - internal static extern int oni_set_opt(ContextHandle ctx, int option, IntPtr val, int size); - - [DllImport(LibraryName, CallingConvention = CCCdecl)] - internal static extern int oni_set_opt(ContextHandle ctx, int option, string val, int size); - - [DllImport(LibraryName, CallingConvention = CCCdecl)] - internal static extern IntPtr oni_get_driver_info(ContextHandle ctx); - - [DllImport(LibraryName, CallingConvention = CCCdecl)] - internal static extern int oni_get_driver_opt(ContextHandle ctx, int option, IntPtr val, IntPtr size); - - [DllImport(LibraryName, CallingConvention = CCCdecl)] - internal static extern int oni_get_driver_opt(ContextHandle ctx, int option, StringBuilder val, IntPtr size); - - [DllImport(LibraryName, CallingConvention = CCCdecl)] - internal static extern int oni_set_driver_opt(ContextHandle ctx, int option, IntPtr val, int size); - - [DllImport(LibraryName, CallingConvention = CCCdecl)] - internal static extern int oni_set_driver_opt(ContextHandle ctx, int option, string val, int size); - - [DllImport(LibraryName, CallingConvention = CCCdecl)] - internal static extern int oni_read_reg(ContextHandle ctx, uint dev_idx, uint addr, IntPtr val); - - [DllImport(LibraryName, CallingConvention = CCCdecl)] - internal static extern int oni_write_reg(ContextHandle ctx, uint dev_idx, uint addr, uint val); - - //[DllImport(LibraryName, CallingConvention = CCCdecl, SetLastError = true)] - //internal static extern int oni_read_frame(ContextHandle ctx, out Frame frame); - - [DllImport(LibraryName, CallingConvention = CCCdecl, SetLastError = true)] - internal static extern int oni_read_frame(ContextHandle ctx, out IntPtr frame); - - //[DllImport(LibraryName, CallingConvention = CCCdecl, SetLastError = true)] - //internal static extern int oni_create_frame(ContextHandle ctx, out Frame frame, uint dev_idx, IntPtr data, uint data_sz); - - //[DllImport(LibraryName, CallingConvention = CCCdecl, SetLastError = true)] - //internal static extern int oni_write_frame(ContextHandle ctx, Frame frame); - - [DllImport(LibraryName, CallingConvention = CCCdecl, SetLastError = true)] - internal static extern int oni_create_frame(ContextHandle ctx, out IntPtr frame, uint dev_idx, IntPtr data, uint data_sz); - - [DllImport(LibraryName, CallingConvention = CCCdecl, SetLastError = true)] - internal static extern int oni_write_frame(ContextHandle ctx, IntPtr frame); - - [DllImport(LibraryName, CallingConvention = CCCdecl)] - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] - internal static extern void oni_destroy_frame(IntPtr frame); - - [DllImport(LibraryName, CallingConvention = CCCdecl)] - internal static extern IntPtr oni_error_str(int err); -#endif - } -} From 52ad31ccd7d755d24f5e3a8b9ee584ad583b569f Mon Sep 17 00:00:00 2001 From: Aaron Cuevas Lopez <1830303+aacuevas@users.noreply.github.com> Date: Tue, 30 Sep 2025 18:52:14 +0200 Subject: [PATCH 4/5] Add files not included by mistake --- api/clroni/clroni/NativeMethods.Common.cs | 46 ++++++++++ api/clroni/clroni/NativeMethods.Framework.cs | 84 +++++++++++++++++ api/clroni/clroni/NativeMethods.NET8.cs | 96 ++++++++++++++++++++ 3 files changed, 226 insertions(+) create mode 100644 api/clroni/clroni/NativeMethods.Common.cs create mode 100644 api/clroni/clroni/NativeMethods.Framework.cs create mode 100644 api/clroni/clroni/NativeMethods.NET8.cs diff --git a/api/clroni/clroni/NativeMethods.Common.cs b/api/clroni/clroni/NativeMethods.Common.cs new file mode 100644 index 0000000..c18b31b --- /dev/null +++ b/api/clroni/clroni/NativeMethods.Common.cs @@ -0,0 +1,46 @@ +using System; +using System.Runtime.InteropServices; +using System.Security; +using System.Text; + +namespace oni +{ + /// + /// Common language runtime bindings to liboni C library. The functionality + /// these bindings is exposed through higher-order types: , + /// , , , + /// and . + /// + [SuppressUnmanagedCodeSecurity] // NB: Call into native code without incurring the performance loss of a run-time security check when doing so + public static partial class NativeMethods + { + /// + /// Semantic version of this library. + /// + public static readonly Version LibraryVersion; + + const string LibraryName = "liboni"; + + static NativeMethods() + { + // Set once LibraryVersion to version() + oni_version(out int major, out int minor, out int patch); + LibraryVersion = new Version(major, minor, patch); + + // Make sure it is supported + if (major < 4) + { + throw VersionNotSupported(null, ">= v4.0.0"); + } + } + + private static NotSupportedException VersionNotSupported(string methodName, string requiredVersion) + { + return new NotSupportedException( + string.Format( + "{0}liboni version not supported. Required version {1}", + methodName == null ? string.Empty : methodName + ": ", + requiredVersion)); + } + } +} diff --git a/api/clroni/clroni/NativeMethods.Framework.cs b/api/clroni/clroni/NativeMethods.Framework.cs new file mode 100644 index 0000000..a26dc10 --- /dev/null +++ b/api/clroni/clroni/NativeMethods.Framework.cs @@ -0,0 +1,84 @@ +using oni; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.ConstrainedExecution; +using System.Runtime.InteropServices; +using System.Text; + +namespace oni +{ + public static partial class NativeMethods + { + private const CallingConvention CCCdecl = CallingConvention.Cdecl; + internal static extern void oni_version(out int major, out int minor, out int patch); + + [DllImport(LibraryName, CallingConvention = CCCdecl, CharSet = CharSet.Ansi)] + internal static extern ContextHandle oni_create_ctx(string driver_name); + + [DllImport(LibraryName, CallingConvention = CCCdecl)] + internal static extern int oni_init_ctx(ContextHandle ctx, int host_idx); + + [DllImport(LibraryName, CallingConvention = CCCdecl)] + [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] + internal static extern int oni_destroy_ctx(IntPtr ctx); + + [DllImport(LibraryName, CallingConvention = CCCdecl)] + internal static extern int oni_get_opt(ContextHandle ctx, int option, IntPtr val, IntPtr size); + + [DllImport(LibraryName, CallingConvention = CCCdecl)] + internal static extern int oni_get_opt(ContextHandle ctx, int option, StringBuilder val, IntPtr size); + + [DllImport(LibraryName, CallingConvention = CCCdecl)] + internal static extern int oni_set_opt(ContextHandle ctx, int option, IntPtr val, int size); + + [DllImport(LibraryName, CallingConvention = CCCdecl)] + internal static extern int oni_set_opt(ContextHandle ctx, int option, string val, int size); + + [DllImport(LibraryName, CallingConvention = CCCdecl)] + internal static extern IntPtr oni_get_driver_info(ContextHandle ctx); + + [DllImport(LibraryName, CallingConvention = CCCdecl)] + internal static extern int oni_get_driver_opt(ContextHandle ctx, int option, IntPtr val, IntPtr size); + + [DllImport(LibraryName, CallingConvention = CCCdecl)] + internal static extern int oni_get_driver_opt(ContextHandle ctx, int option, StringBuilder val, IntPtr size); + + [DllImport(LibraryName, CallingConvention = CCCdecl)] + internal static extern int oni_set_driver_opt(ContextHandle ctx, int option, IntPtr val, int size); + + [DllImport(LibraryName, CallingConvention = CCCdecl)] + internal static extern int oni_set_driver_opt(ContextHandle ctx, int option, string val, int size); + + [DllImport(LibraryName, CallingConvention = CCCdecl)] + internal static extern int oni_read_reg(ContextHandle ctx, uint dev_idx, uint addr, IntPtr val); + + [DllImport(LibraryName, CallingConvention = CCCdecl)] + internal static extern int oni_write_reg(ContextHandle ctx, uint dev_idx, uint addr, uint val); + + //[DllImport(LibraryName, CallingConvention = CCCdecl, SetLastError = true)] + //internal static extern int oni_read_frame(ContextHandle ctx, out Frame frame); + + [DllImport(LibraryName, CallingConvention = CCCdecl, SetLastError = true)] + internal static extern int oni_read_frame(ContextHandle ctx, out IntPtr frame); + + //[DllImport(LibraryName, CallingConvention = CCCdecl, SetLastError = true)] + //internal static extern int oni_create_frame(ContextHandle ctx, out Frame frame, uint dev_idx, IntPtr data, uint data_sz); + + //[DllImport(LibraryName, CallingConvention = CCCdecl, SetLastError = true)] + //internal static extern int oni_write_frame(ContextHandle ctx, Frame frame); + + [DllImport(LibraryName, CallingConvention = CCCdecl, SetLastError = true)] + internal static extern int oni_create_frame(ContextHandle ctx, out IntPtr frame, uint dev_idx, IntPtr data, uint data_sz); + + [DllImport(LibraryName, CallingConvention = CCCdecl, SetLastError = true)] + internal static extern int oni_write_frame(ContextHandle ctx, IntPtr frame); + + [DllImport(LibraryName, CallingConvention = CCCdecl)] + [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] + internal static extern void oni_destroy_frame(IntPtr frame); + + [DllImport(LibraryName, CallingConvention = CCCdecl)] + internal static extern IntPtr oni_error_str(int err); + } +} diff --git a/api/clroni/clroni/NativeMethods.NET8.cs b/api/clroni/clroni/NativeMethods.NET8.cs new file mode 100644 index 0000000..f041929 --- /dev/null +++ b/api/clroni/clroni/NativeMethods.NET8.cs @@ -0,0 +1,96 @@ +using System; +using System.Runtime.InteropServices; +using System.Security; +using System.Runtime.CompilerServices; + +namespace oni +{ + public static partial class NativeMethods + { + [LibraryImport(LibraryName)] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + internal static partial void oni_version(out int major, out int minor, out int patch); + + [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern ContextHandle oni_create_ctx(string driver_name); + + [LibraryImport(LibraryName)] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + internal static partial int oni_init_ctx(ContextHandle ctx, int host_idx); + + [LibraryImport(LibraryName)] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + internal static partial int oni_destroy_ctx(IntPtr ctx); + + [LibraryImport(LibraryName)] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + internal static partial int oni_get_opt(ContextHandle ctx, int option, IntPtr val, IntPtr size); + + [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern int oni_get_opt(ContextHandle ctx, int option, [Out] char[] val, IntPtr size); + + [LibraryImport(LibraryName)] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + internal static partial int oni_set_opt(ContextHandle ctx, int option, IntPtr val, int size); + + [LibraryImport(LibraryName, StringMarshalling = StringMarshalling.Utf8)] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + internal static partial int oni_set_opt(ContextHandle ctx, int option, string val, int size); + + [LibraryImport(LibraryName)] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + internal static partial IntPtr oni_get_driver_info(ContextHandle ctx); + + [LibraryImport(LibraryName)] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + internal static partial int oni_get_driver_opt(ContextHandle ctx, int option, IntPtr val, IntPtr size); + + [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] + internal static extern int oni_get_driver_opt(ContextHandle ctx, int option, [Out] char[] val, IntPtr size); + + [LibraryImport(LibraryName)] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + internal static partial int oni_set_driver_opt(ContextHandle ctx, int option, IntPtr val, int size); + + [LibraryImport(LibraryName, StringMarshalling = StringMarshalling.Utf8)] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + internal static partial int oni_set_driver_opt(ContextHandle ctx, int option, string val, int size); + + [LibraryImport(LibraryName)] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + internal static partial int oni_read_reg(ContextHandle ctx, uint dev_idx, uint addr, IntPtr val); + + [LibraryImport(LibraryName)] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + internal static partial int oni_write_reg(ContextHandle ctx, uint dev_idx, uint addr, uint val); + + //[DllImport(LibraryName, CallingConvention = CCCdecl, SetLastError = true)] + //internal static extern int oni_read_frame(ContextHandle ctx, out Frame frame); + + [LibraryImport(LibraryName, SetLastError = true)] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + internal static partial int oni_read_frame(ContextHandle ctx, out IntPtr frame); + + //[DllImport(LibraryName, CallingConvention = CCCdecl, SetLastError = true)] + //internal static extern int oni_create_frame(ContextHandle ctx, out Frame frame, uint dev_idx, IntPtr data, uint data_sz); + + //[DllImport(LibraryName, CallingConvention = CCCdecl, SetLastError = true)] + //internal static extern int oni_write_frame(ContextHandle ctx, Frame frame); + + [LibraryImport(LibraryName, SetLastError = true)] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + internal static partial int oni_create_frame(ContextHandle ctx, out IntPtr frame, uint dev_idx, IntPtr data, uint data_sz); + + [LibraryImport(LibraryName, SetLastError = true)] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + internal static partial int oni_write_frame(ContextHandle ctx, IntPtr frame); + + [LibraryImport(LibraryName)] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + internal static partial void oni_destroy_frame(IntPtr frame); + + [LibraryImport(LibraryName)] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + internal static partial IntPtr oni_error_str(int err); + } +} From 6be19217c235de964265ff04d719b8ef9eed7566 Mon Sep 17 00:00:00 2001 From: Aaron Cuevas Lopez <1830303+aacuevas@users.noreply.github.com> Date: Tue, 30 Sep 2025 23:31:15 +0200 Subject: [PATCH 5/5] Fix dependencies not being always found --- api/clroni/clroni/NativeMethods.Framework.cs | 2 ++ api/clroni/clroni/clroni.csproj | 4 ++-- api/clroni/clroni/clroni.targets | 8 ++++---- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/api/clroni/clroni/NativeMethods.Framework.cs b/api/clroni/clroni/NativeMethods.Framework.cs index a26dc10..f567432 100644 --- a/api/clroni/clroni/NativeMethods.Framework.cs +++ b/api/clroni/clroni/NativeMethods.Framework.cs @@ -11,6 +11,8 @@ namespace oni public static partial class NativeMethods { private const CallingConvention CCCdecl = CallingConvention.Cdecl; + + [DllImport(LibraryName, CallingConvention = CCCdecl, CharSet = CharSet.Ansi)] internal static extern void oni_version(out int major, out int minor, out int patch); [DllImport(LibraryName, CallingConvention = CCCdecl, CharSet = CharSet.Ansi)] diff --git a/api/clroni/clroni/clroni.csproj b/api/clroni/clroni/clroni.csproj index 49715de..f0e40b2 100644 --- a/api/clroni/clroni/clroni.csproj +++ b/api/clroni/clroni/clroni.csproj @@ -6,7 +6,7 @@ ONI Open Ephys ONIX net8.0;net472;netstandard2.0 false - 6.3.0-dev1 + 6.3.0-dev4 Jon Newman Open Ephys, Inc. ©Open Ephys, Inc. @@ -77,7 +77,7 @@ - + diff --git a/api/clroni/clroni/clroni.targets b/api/clroni/clroni/clroni.targets index 6343f67..87492f4 100644 --- a/api/clroni/clroni/clroni.targets +++ b/api/clroni/clroni/clroni.targets @@ -10,14 +10,14 @@ - - + + true - - + + true