Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 9 additions & 14 deletions api/clroni/clroni-repl/Repl.cs
Original file line number Diff line number Diff line change
@@ -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()
{
Expand Down Expand Up @@ -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:
Expand Down
7 changes: 4 additions & 3 deletions api/clroni/clroni-repl/clroni-repl.csproj
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<Title>ONI RELLPL (RCRLLR)(CLR)</Title>
<Title>ONI REPL</Title>
<Description>Test application for clroni.</Description>
<PackageTags>ONI Open Ephys</PackageTags>
<TargetFramework>net472</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Version>1.2.2</Version>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<Copyright>Copyright © Open Ephys, Inc.</Copyright>
Expand Down
18 changes: 15 additions & 3 deletions api/clroni/clroni/Context.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Security.Permissions;
using System.Text;


namespace oni
{
/// <summary>
Expand Down Expand Up @@ -183,17 +184,24 @@ 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);

#if NET7_0_OR_GREATER
var str = new char[BufferSize];
#else
var str = new StringBuilder(BufferSize);
#endif

int rc;
if (!drv_opt)
Expand Down Expand Up @@ -555,8 +563,12 @@ public void Dispose()
/// by IDisposable.
/// </summary>
/// <param name="disposing"></param>
#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)
Expand Down
8 changes: 6 additions & 2 deletions api/clroni/clroni/ContextHandle.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,19 @@
using System.Runtime.ConstrainedExecution;
using System.Security.Permissions;


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) { }

[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
protected override bool ReleaseHandle()
{
return NativeMethods.oni_destroy_ctx(handle) == 0;
Expand Down
11 changes: 10 additions & 1 deletion api/clroni/clroni/Frame.cs
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
using Microsoft.Win32.SafeHandles;
using System;
using System.Runtime.ConstrainedExecution;
using System.Runtime.InteropServices;
using System.Runtime.ConstrainedExecution;
using System.Security.Permissions;


namespace oni
{
/// <summary>
/// Managed wrapper for an ONI-compliant data frame implementation. Produced by calls
/// to <see cref="Context.ReadFrame"/> .
/// </summary>
#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)]
Expand All @@ -36,8 +41,12 @@ internal Frame(IntPtr handle)
/// </summary>
/// <returns>True if the handle is released successfully (always the case
/// in this implementation)</returns>
#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);
Expand Down
46 changes: 46 additions & 0 deletions api/clroni/clroni/NativeMethods.Common.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
using System;
using System.Runtime.InteropServices;
using System.Security;
using System.Text;

namespace oni
{
/// <summary>
/// Common language runtime bindings to liboni C library. The functionality
/// these bindings is exposed through higher-order types: <seealso cref="Context"/>,
/// <seealso cref="Hub"/>, <seealso cref="Device"/>, <seealso cref="Frame"/>,
/// and <seealso cref="ONIException"/>.
/// </summary>
[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
{
/// <summary>
/// <see href="https://semver.org/">Semantic version</see> of this library.
/// </summary>
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));
}
}
}
Original file line number Diff line number Diff line change
@@ -1,56 +1,18 @@
using oni;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.ConstrainedExecution;
using System.Runtime.InteropServices;
using System.Security;
using System.Text;

namespace oni
{
/// <summary>
/// Common language runtime bindings to liboni C library. The functionality
/// these bindings is exposed through higher-order types: <seealso cref="Context"/>,
/// <seealso cref="Hub"/>, <seealso cref="Device"/>, <seealso cref="Frame"/>,
/// and <seealso cref="ONIException"/>.
/// </summary>
[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
{
/// <summary>
/// <see href="https://semver.org/">Semantic version</see> of this library.
/// </summary>
public static readonly Version LibraryVersion;

private const CallingConvention CCCdecl = CallingConvention.Cdecl;

private const string LibraryName = "liboni";

// The static constructor prepares static readonly fields
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));
}




[DllImport(LibraryName, CallingConvention = CCCdecl)]
[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)]
Expand Down
96 changes: 96 additions & 0 deletions api/clroni/clroni/NativeMethods.NET8.cs
Original file line number Diff line number Diff line change
@@ -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);
}
}
Loading