Skip to content

Commit

Permalink
[FSharp] Move pin utilities to modules; add pinArri, temp
Browse files Browse the repository at this point in the history
  • Loading branch information
hyazinthh committed Sep 4, 2024
1 parent 5074804 commit 9ff0da9
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 10 deletions.
20 changes: 20 additions & 0 deletions src/Aardvark.Base.FSharp/Utilities/Interop/FSLibExtensions.fs
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,26 @@ module Prelude =
let l = int64 <| sizeof<'a> * count
new System.IO.UnmanagedMemoryStream(cast ptr, l,l, FileAccess.ReadWrite) :> _

/// Pins the given value and invokes the action with the native pointer.
/// Note: Use a fixed expression with a byref if writing to the original location is required.
let inline pin<'T, 'U when 'T : unmanaged> ([<InlineIfLambda>] action: nativeptr<'T> -> 'U) (value: 'T) =
use ptr = fixed &value
action ptr

/// Pins the given array and invokes the action with the native pointer.
let inline pinArr<'T, 'U when 'T : unmanaged> ([<InlineIfLambda>] action: nativeptr<'T> -> 'U) (array: 'T[]) =
use ptr = fixed array
action ptr

/// Pins the given array at the given index and invokes the action with the native pointer.
let inline pinArri<'T, 'U when 'T : unmanaged> ([<InlineIfLambda>] action: nativeptr<'T> -> 'U) (index: int) (array: 'T[]) =
use ptr = fixed &array.[index]
action ptr

/// Allocates a temporary native pointer and invokes the action.
let inline temp<'T, 'U when 'T : unmanaged> ([<InlineIfLambda>] action: nativeptr<'T> -> 'U) =
pin action Unchecked.defaultof<'T>

module Operators =

let ( &+ ) (ptr : nativeptr<'a>) (count : int) =
Expand Down
22 changes: 12 additions & 10 deletions src/Aardvark.Base.FSharp/Utilities/Native.fs
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,12 @@ module NativeUtilities =
let inline set<'a when 'a : unmanaged> (ptr : nativeint) (index : int) (value : 'a)=
NativePtr.set (NativePtr.ofNativeInt<'a> ptr) index value

/// Pins the given object and invokes the action with its address.
let inline pin ([<InlineIfLambda>] action: nativeint -> 'T) (value: obj) =
let gc = GCHandle.Alloc(value, GCHandleType.Pinned)
try action <| gc.AddrOfPinnedObject()
finally gc.Free()

type Marshal with
static member Copy(source : nativeint, destination : nativeint, length : unativeint) =
match os with
Expand Down Expand Up @@ -174,21 +180,17 @@ module NativeUtilities =
static member inline Compare(source : nativeint, destination : nativeint, length : 'a) =
Marshal.Compare(source, destination, unativeint length)


[<Obsolete("Use NativeInt.pin instead.")>]
let pinned (a : obj) f =
let gc = GCHandle.Alloc(a, GCHandleType.Pinned)
try
f ( gc.AddrOfPinnedObject() )
finally
gc.Free()
NativeInt.pin f a

[<Obsolete("Use NativePtr.pin instead.")>]
let inline pin ([<InlineIfLambda>] f: nativeptr<'T> -> 'U) (value: 'T) =
use ptr = fixed &value
f ptr
NativePtr.pin f value

[<Obsolete("Use NativePtr.pinArr instead.")>]
let inline pinArr ([<InlineIfLambda>] f: nativeptr<'T> -> 'U) (array: 'T[]) =
use ptr = fixed array
f ptr
NativePtr.pinArr f array

[<AutoOpen>]
module MarshalDelegateExtensions =
Expand Down

0 comments on commit 9ff0da9

Please sign in to comment.