13 people like it.
Like the snippet!
F# yet another Interop example
Quick demo of using F# to interop with a native C library. C Library has not been checked for algorithm correctness (but works exactly as the origional).
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
|
boyer-moore.c
module native =
module string_search =
open System.Text
open System.Runtime.InteropServices
[<DllImport(@"boyermoore.dll", EntryPoint="boyerMoore", CharSet = CharSet.Ansi)>]
extern nativeint boyerMoore(nativeint data, nativeint search)
let alloc_a (data : string) =
let strbuf = Encoding.UTF8.GetBytes data
let buffer = Marshal.AllocHGlobal(strbuf.Length + 1)
Marshal.Copy(strbuf, 0, buffer, strbuf.Length)
Marshal.WriteByte( buffer + (nativeint strbuf.Length), 0uy)
buffer
let bMoore data search =
let d,s = alloc_a <| data, alloc_a <| search
let x = Marshal.PtrToStringAnsi(boyerMoore(d,s) )
Marshal.FreeHGlobal d
Marshal.FreeHGlobal s
x
native.string_search.bMoore "aaaabouaaa384982n chwercoiewar45u0943 twert3aaaaaaMarabou t9034u5t09t8493t43vkdsropgb" "Marabou"
|
(*
/*
Simple implementation of the fast Boyer-Moore string search algorithm.
By X-Calibre, 2002
- slight modifications by davidk (main removed, cdecl added, casting for return types)
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
#include <strsafe.h>
#define EXTERN_DLL_EXPORT extern "C" __declspec(dllexport)
char *BoyerMoore( unsigned char *data, unsigned int dataLength, unsigned char *string, unsigned int strLength ) {
unsigned int skipTable[256], i;
unsigned char *search;
register unsigned char lastChar;
if (strLength == 0)
return NULL;
// Initialize skip lookup table
for (i = 0; i < 256; i++)
skipTable[i] = strLength;
search = string;
// Decrease strLength here to make it an index
i = --strLength;
do
{
skipTable[*search++] = i;
} while (i--);
lastChar = *--search;
// Start searching, position pointer at possible end of string.
search = data + strLength;
dataLength -= strLength+(strLength-1);
while ((int)dataLength > 0 )
{
unsigned int skip;
skip = skipTable[*search];
search += skip;
dataLength -= skip;
skip = skipTable[*search];
search += skip;
dataLength -= skip;
skip = skipTable[*search];
if (*search != lastChar) /*if (skip > 0)*/
{
// Character does not match, realign string and try again
search += skip;
dataLength -= skip;
continue;
}
// We had a match, we could be at the end of the string
i = strLength;
do
{
// Have we found the entire string?
if (i-- == 0)
return (char * )search;
} while (*--search == string[i]);
// Skip past the part of the string that we scanned already
search += (strLength - i + 1);
dataLength--;
}
// We reached the end of the data, and didn't find the string
return NULL;
}
EXTERN_DLL_EXPORT
char *boyerMoore(unsigned char *data, unsigned char *search) {
char *str = BoyerMoore( data, strlen((const char *)data), search, strlen((const char *)search) );
if (str == NULL)
return "String not found";
else
return str;
return "";
}
*)
module string_search
from Script.native
namespace System
namespace System.Text
namespace System.Runtime
namespace System.Runtime.InteropServices
Multiple items
type DllImportAttribute =
inherit Attribute
new : dllName:string -> DllImportAttribute
val EntryPoint : string
val CharSet : CharSet
val SetLastError : bool
val ExactSpelling : bool
val PreserveSig : bool
val CallingConvention : CallingConvention
val BestFitMapping : bool
val ThrowOnUnmappableChar : bool
member Value : string
Full name: System.Runtime.InteropServices.DllImportAttribute
--------------------
DllImportAttribute(dllName: string) : unit
Multiple items
type EntryPointAttribute =
inherit Attribute
new : unit -> EntryPointAttribute
Full name: Microsoft.FSharp.Core.EntryPointAttribute
--------------------
new : unit -> EntryPointAttribute
type CharSet =
| None = 1
| Ansi = 2
| Unicode = 3
| Auto = 4
Full name: System.Runtime.InteropServices.CharSet
field CharSet.Ansi = 2
Multiple items
val nativeint : value:'T -> nativeint (requires member op_Explicit)
Full name: Microsoft.FSharp.Core.Operators.nativeint
--------------------
type nativeint = System.IntPtr
Full name: Microsoft.FSharp.Core.nativeint
val boyerMoore : data:nativeint * search:nativeint -> nativeint
Full name: Script.native.string_search.boyerMoore
val data : nativeint
val search : nativeint
val alloc_a : data:string -> nativeint
Full name: Script.native.string_search.alloc_a
val data : string
Multiple items
val string : value:'T -> string
Full name: Microsoft.FSharp.Core.Operators.string
--------------------
type string = System.String
Full name: Microsoft.FSharp.Core.string
val strbuf : byte []
type Encoding =
member BodyName : string
member Clone : unit -> obj
member CodePage : int
member DecoderFallback : DecoderFallback with get, set
member EncoderFallback : EncoderFallback with get, set
member EncodingName : string
member Equals : value:obj -> bool
member GetByteCount : chars:char[] -> int + 3 overloads
member GetBytes : chars:char[] -> byte[] + 5 overloads
member GetCharCount : bytes:byte[] -> int + 2 overloads
...
Full name: System.Text.Encoding
property Encoding.UTF8: Encoding
Encoding.GetBytes(s: string) : byte []
Encoding.GetBytes(chars: char []) : byte []
Encoding.GetBytes(chars: char [], index: int, count: int) : byte []
Encoding.GetBytes(chars: nativeptr<char>, charCount: int, bytes: nativeptr<byte>, byteCount: int) : int
Encoding.GetBytes(s: string, charIndex: int, charCount: int, bytes: byte [], byteIndex: int) : int
Encoding.GetBytes(chars: char [], charIndex: int, charCount: int, bytes: byte [], byteIndex: int) : int
val buffer : nativeint
type Marshal =
static val SystemDefaultCharSize : int
static val SystemMaxDBCSCharSize : int
static member AddRef : pUnk:nativeint -> int
static member AllocCoTaskMem : cb:int -> nativeint
static member AllocHGlobal : cb:nativeint -> nativeint + 1 overload
static member AreComObjectsAvailableForCleanup : unit -> bool
static member BindToMoniker : monikerName:string -> obj
static member ChangeWrapperHandleStrength : otp:obj * fIsWeak:bool -> unit
static member CleanupUnusedObjectsInCurrentContext : unit -> unit
static member Copy : source:int[] * startIndex:int * destination:nativeint * length:int -> unit + 15 overloads
...
Full name: System.Runtime.InteropServices.Marshal
Marshal.AllocHGlobal(cb: int) : nativeint
Marshal.AllocHGlobal(cb: nativeint) : nativeint
property System.Array.Length: int
Marshal.Copy(source: nativeint, destination: nativeint [], startIndex: int, length: int) : unit
(+0 other overloads)
Marshal.Copy(source: nativeint, destination: byte [], startIndex: int, length: int) : unit
(+0 other overloads)
Marshal.Copy(source: nativeint, destination: float [], startIndex: int, length: int) : unit
(+0 other overloads)
Marshal.Copy(source: nativeint, destination: float32 [], startIndex: int, length: int) : unit
(+0 other overloads)
Marshal.Copy(source: nativeint, destination: int64 [], startIndex: int, length: int) : unit
(+0 other overloads)
Marshal.Copy(source: nativeint, destination: int16 [], startIndex: int, length: int) : unit
(+0 other overloads)
Marshal.Copy(source: nativeint, destination: char [], startIndex: int, length: int) : unit
(+0 other overloads)
Marshal.Copy(source: nativeint, destination: int [], startIndex: int, length: int) : unit
(+0 other overloads)
Marshal.Copy(source: nativeint [], startIndex: int, destination: nativeint, length: int) : unit
(+0 other overloads)
Marshal.Copy(source: byte [], startIndex: int, destination: nativeint, length: int) : unit
(+0 other overloads)
Marshal.WriteByte(ptr: nativeint, val: byte) : unit
Marshal.WriteByte(ptr: obj, ofs: int, val: byte) : unit
Marshal.WriteByte(ptr: nativeint, ofs: int, val: byte) : unit
val bMoore : data:string -> search:string -> string
Full name: Script.native.string_search.bMoore
val search : string
val d : nativeint
val s : nativeint
val x : string
Marshal.PtrToStringAnsi(ptr: nativeint) : string
Marshal.PtrToStringAnsi(ptr: nativeint, len: int) : string
Marshal.FreeHGlobal(hglobal: nativeint) : unit
module native
from Script
More information