NextPrevUpTopContentsIndex

4.2.5 Foreign string encodings

The :ef-mb-string type is capable of converting between the internal encoding of LispWorks strings (Unicode) and various encodings that may be expected by the foreign code. The encoding on the foreign side is specified by the :external-format argument, which takes an External Format specification.. See the LispWorks User Guide for a more detailed description of external formats.

Conside a variant of the last example where the returned string contains characters beyond the ASCII range.

Windows version:

#include <string.h>
#include <stdlib.h>
 
__declspec(dllexport) void __cdecl random_string2(int length, char *string)
{
  int ii;
  for (ii = 0; ii < length ; ii++)
      string[ii] = 225 + rand() % 26;
  string[length] = 0;
}

Linux/Unix/Macintosh version:

#include <string.h>
#include <stdlib.h>
 
void random_string2(int length, char *string)
{
  int ii;
  for (ii = 0; ii < length ; ii++)
      string[ii] = 225 + rand() % 26;
  string[length] = 0;
}

A foreign function defined like random-string above is inadequate by itself here because the default external format is that for the default C locale, ASCII. This will signal error when it encounters a non-ASCII character code. There are two approaches to handling non-ASCII characters.

1. Pass an appropriate external format, in this case it is Latin-1:

(fli:define-foreign-function (random-string2 
                              "random_string2" 
                              :source)
   ((length :int)
    (return-string (:reference-return 
                    (:ef-mb-string 
                     :limit 256
                     :external-format :latin-1))))
 :result-type nil
 :lambda-list (length &aux return-string)
 :calling-convention :cdecl)
 
(random-string2 3)
=>
"òãö"
 
(random-string2 6)
=>
"óãøççâ"

2. Set the locale, using set-locale. This sets the C locale and switches the FLI to use an appropriate default wherever an external-format argument is accepted.

(fli:define-foreign-function (random-string 
                              "random_string2" 
                              :source)
   ((length :int)
    (return-string (:reference-return 
                    (:ef-mb-string 
                     :limit 256))))
 :result-type nil
 :lambda-list (length &aux return-string)
 :calling-convention :cdecl)

On a Windows system with current Code Page for Western European languages:

(fli:set-locale)
=>
(win32:code-page :id 1252)

On a Unix/Linux system with a Latin-1/ISO8859-1 default locale:

(fli:set-locale)
=>
:latin-1

After the default external-format has been switched:

(random-string 6)
=> 
"≤èñçèõ"

If you do not actually wish to set the C locale, you can call set-locale-encodings which merely switches the FLI to use the specified external formats where an external-format argument is accepted.


LispWorks Foreign Language Interface User Guide and Reference Manual - 14 Mar 2008

NextPrevUpTopContentsIndex