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)
*/
# <stdio.h>
# <stdlib.h>
# <string.h>
# <windows.h>
# <strsafe.h>
# 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 "";
}
namespace System
namespace System.Text
namespace System.Runtime
namespace System.Runtime.InteropServices
Multiple items
type EntryPointAttribute =
inherit Attribute
new : unit -> EntryPointAttribute
Full name: Microsoft.FSharp.Core.EntryPointAttribute
--------------------
new : unit -> EntryPointAttribute
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
Multiple items
val string : value:'T -> string
Full name: Microsoft.FSharp.Core.Operators.string
--------------------
type string = System.String
Full name: Microsoft.FSharp.Core.string
More information