Skip to content

Commit 2ce621c

Browse files
authored
IntPtr F# snippets (#7754)
1 parent c3bab69 commit 2ce621c

File tree

16 files changed

+326
-4
lines changed

16 files changed

+326
-4
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// <Snippet1>
2+
#nowarn "9"
3+
open System
4+
open System.Runtime.InteropServices
5+
open FSharp.NativeInterop
6+
7+
[<EntryPoint>]
8+
let main _ =
9+
let mutable arr =
10+
[| 2; 4; 6; 8; 10; 12; 14; 16; 18; 20 |]
11+
12+
use parr = fixed arr
13+
14+
let ptr = NativePtr.toNativeInt parr
15+
16+
// Get the size of an array element.
17+
let size = sizeof<int>
18+
for i = 0 to arr.Length - 1 do
19+
let newPtr = IntPtr.Add(ptr, i * size)
20+
printf $"{Marshal.ReadInt32 newPtr} "
21+
0
22+
23+
// The example displays the following output:
24+
// 2 4 6 8 10 12 14 16 18 20
25+
// </Snippet1>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<OutputType>Exe</OutputType>
4+
<TargetFramework>net6.0</TargetFramework>
5+
</PropertyGroup>
6+
7+
<ItemGroup>
8+
<Compile Include="add1.fs" />
9+
</ItemGroup>
10+
</Project>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<OutputType>Exe</OutputType>
4+
<TargetFramework>net6.0</TargetFramework>
5+
</PropertyGroup>
6+
7+
<ItemGroup>
8+
<Compile Include="topointer.fs" />
9+
</ItemGroup>
10+
</Project>
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
//<snippet1>
2+
#nowarn "9"
3+
open System.Runtime.InteropServices
4+
open FSharp.NativeInterop
5+
6+
[<EntryPoint>]
7+
let main _ =
8+
let stringA = "I seem to be turned around!"
9+
let mutable copylen = stringA.Length
10+
11+
// Allocate HGlobal memory for source and destination strings
12+
let sptr = Marshal.StringToHGlobalAnsi stringA
13+
let dptr = Marshal.AllocHGlobal(copylen + 1)
14+
15+
let mutable src: byte nativeptr = sptr.ToPointer() |> NativePtr.ofVoidPtr
16+
let mutable dst: byte nativeptr = dptr.ToPointer() |> NativePtr.ofVoidPtr
17+
18+
if copylen > 0 then
19+
// set the source pointer to the end of the string
20+
// to do a reverse copy.
21+
src <-
22+
NativePtr.toNativeInt src + nativeint (copylen - 1)
23+
|> NativePtr.ofNativeInt
24+
25+
while copylen > 0 do
26+
copylen <- copylen - 1
27+
NativePtr.read src |> NativePtr.write dst
28+
dst <- NativePtr.toNativeInt dst + 1n |> NativePtr.ofNativeInt
29+
src <- NativePtr.toNativeInt src - 1n |> NativePtr.ofNativeInt
30+
NativePtr.write dst 0uy
31+
32+
let stringB = Marshal.PtrToStringAnsi dptr
33+
34+
printfn $"Original:\n{stringA}\n"
35+
printfn $"Reversed:\n{stringB}"
36+
37+
// Free HGlobal memory
38+
Marshal.FreeHGlobal dptr
39+
Marshal.FreeHGlobal sptr
40+
0
41+
42+
// The progam has the following output:
43+
//
44+
// Original:
45+
// I seem to be turned around!
46+
//
47+
// Reversed:
48+
// !dnuora denrut eb ot mees I
49+
//</snippet1>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<OutputType>Exe</OutputType>
4+
<TargetFramework>net6.0</TargetFramework>
5+
</PropertyGroup>
6+
7+
<ItemGroup>
8+
<Compile Include="subtract1.fs" />
9+
</ItemGroup>
10+
</Project>
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// <Snippet1>
2+
#nowarn "9"
3+
open System
4+
open System.Runtime.InteropServices
5+
open FSharp.NativeInterop
6+
7+
[<EntryPoint>]
8+
let main _ =
9+
let arr =
10+
[| 2; 4; 6; 8; 10; 12; 14; 16; 18; 20 |]
11+
12+
// Get the size of a single array element.
13+
let size = sizeof<int>
14+
15+
use pend = fixed &arr[arr.GetUpperBound 0]
16+
let ptr = NativePtr.toNativeInt pend
17+
for i = 0 to arr.Length - 1 do
18+
let newPtr = IntPtr.Subtract(ptr, i * size)
19+
printf $"{Marshal.ReadInt32 newPtr} "
20+
0
21+
22+
// The example displays the following output:
23+
// 20 18 16 14 12 10 8 6 4 2
24+
// </Snippet1>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<OutputType>Exe</OutputType>
4+
<TargetFramework>net6.0</TargetFramework>
5+
</PropertyGroup>
6+
7+
<ItemGroup>
8+
<Compile Include="topointer.fs" />
9+
</ItemGroup>
10+
</Project>
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
//<snippet1>
2+
#nowarn "9"
3+
open System.Runtime.InteropServices
4+
open FSharp.NativeInterop
5+
6+
[<EntryPoint>]
7+
let main _ =
8+
let stringA = "I seem to be turned around!"
9+
let mutable copylen = stringA.Length
10+
11+
// Allocate HGlobal memory for source and destination strings
12+
let sptr = Marshal.StringToHGlobalAnsi stringA
13+
let dptr = Marshal.AllocHGlobal(copylen + 1)
14+
15+
let mutable src: byte nativeptr = sptr.ToPointer() |> NativePtr.ofVoidPtr
16+
let mutable dst: byte nativeptr = dptr.ToPointer() |> NativePtr.ofVoidPtr
17+
18+
if copylen > 0 then
19+
// set the source pointer to the end of the string
20+
// to do a reverse copy.
21+
src <-
22+
NativePtr.toNativeInt src + nativeint (copylen - 1)
23+
|> NativePtr.ofNativeInt
24+
25+
while copylen > 0 do
26+
copylen <- copylen - 1
27+
NativePtr.read src |> NativePtr.write dst
28+
dst <- NativePtr.toNativeInt dst + 1n |> NativePtr.ofNativeInt
29+
src <- NativePtr.toNativeInt src - 1n |> NativePtr.ofNativeInt
30+
NativePtr.write dst 0uy
31+
32+
let stringB = Marshal.PtrToStringAnsi dptr
33+
34+
printfn $"Original:\n{stringA}\n"
35+
printfn $"Reversed:\n{stringB}"
36+
37+
// Free HGlobal memory
38+
Marshal.FreeHGlobal dptr
39+
Marshal.FreeHGlobal sptr
40+
0
41+
42+
// The progam has the following output:
43+
//
44+
// Original:
45+
// I seem to be turned around!
46+
//
47+
// Reversed:
48+
// !dnuora denrut eb ot mees I
49+
//</snippet1>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<OutputType>Exe</OutputType>
4+
<TargetFramework>net6.0</TargetFramework>
5+
</PropertyGroup>
6+
7+
<ItemGroup>
8+
<Compile Include="zero2.fs" />
9+
<Compile Include="zero4.fs" />
10+
</ItemGroup>
11+
</Project>
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
module zero2
2+
3+
// <Snippet1>
4+
open System
5+
open System.Runtime.InteropServices
6+
7+
let GW_OWNER = 4
8+
9+
[<DllImport("user32", CharSet=CharSet.Auto, SetLastError=true, ExactSpelling=true)>]
10+
extern IntPtr GetWindow(nativeint hwnd, int wFlag)
11+
12+
let hwnd = IntPtr 3
13+
let hOwner = GetWindow(hwnd, GW_OWNER)
14+
if hOwner = IntPtr.Zero then
15+
printfn "Window not found."
16+
17+
// The example displays the following output:
18+
// Window not found.
19+
// </Snippet1>

0 commit comments

Comments
 (0)