13 people like it.

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

Link:http://fssnip.net/c1
Posted:11 years ago
Author:David Klein
Tags: f# , interop , boyer moore , string matching