Calling the outside World

World can call routines in dynamic link libraries, and with the addition of handle! and struct! datatypes, all possible calls are supported. Let's see a simple example with the routines "strerror" and "puts" from LIBC:
(Examples are done under OS X.)

    libc: load/library %/usr/lib/libc.dylib

    strerror: make routine! [
        libc "strerror" [
            [] uint
        ]
        pointer
    ]

This is a simple definition of "strerror" without advanced typechecking and no description or specification of argument name or World datatype. "strerror" can now be used like this:

    w> strerror 1
    == "Operation not permitted"

The returned string can be saved in a variable:

    w> str: strerror 1
    == "Operation not permitted"

Then "puts" is defined:

    puts: make routine! [
        libc "puts" [
            [] pointer
        ]
        sint
    ]

And "puts" can be used to write str to stdout:

    w> puts str
    Operation not permitted
    == 10

"strerror" and "puts" can also be defined operating on handles, and in this case the string isn't copied to a World string! datatype. This time, the special attribute, typecheck, is needed, and I'll also put in some extra description and variable names:

    strerror: make routine! [
        "Maps the error code to a descriptive error message."
        [typecheck]
        libc "strerror" [
            errnum [integer!] uint "Error code"
        ]
        pointer handle!
    ]

    puts: make routine! [
        "Writes a string to stdout followed by a newline."
        [typecheck]
        libc "puts" [
            s [handle!] pointer "The string"
        ]
        sint
    ]

Example of use:
(notice "strerror" no longer returns a string)

    w> handle: strerror 1
    w> puts handle
    Operation not permitted
    == 10

Use the help function on a defined routine to see, how the routine is used:

    w> help strerror

1 comment:

  1. Good stuff Geomol. keep up the Good work. Paul T. from REBOL.

    ReplyDelete