The integrated cross-platform development tool for ANSI Common Lisp LispWorks logo

Lisp Knowledgebase



Title: Win32 API and functions that handle strings

ID: 10013


Product: LispWorks for Windows
Version: 4.1
OS: all Windows platforms

Description: Functions in the Win32 API that handle strings come in two flavours, one for ANSI strings and one for Unicode strings. Win95/Win98 only supports the ANSI functions but WinNT supports both. The functions are named with a suffix, an A for the ANSI ones and a W for the Unicode ones. So for example. the two symbols that do exist are CreateFileA and CreateFileW. In C, this is finessed by the use of #define in the header files.

There are two ways to handle this:

1) Always use the A functions. This will allow the code to work on all versions of Windows, but will prevent the use of unicode on WinNT (this is typically only a problem if you are handling mixed language data).

2) Use the :DBCS encoding in FLI:DEFINE-FOREIGN-FUNCTION. This will cause it to switch between ANSI and Unicode versions depending on the OS.

In either case, as well as calling the correct function, you must encode/decode any string arguments/results correctly, to match the A or W in the function name. We have some (as yet undocumented) foreign types which correspond to the typical ones found in the Win32 API:

W:TSTR &key length
An ANSI/Unicode string

W:LPCTSTR &key max-length
A reference-pass pointer to ANSI/Unicode string

W:LPTSTR  &key max-length
A reference (in/out) pointer to an ANSI/Unicode string

Each of the above three types (i.e. the ones with T in their name), automatically switch between ANSI and Unicode, which makes them ideal for use with the :DBCS encoding option in FLI:DEFINE-FOREIGN-FUNCTION.

Example:

;; This calls GetDriveTypeA on Windows 9x, and GetDriveTypeW on NT.
;; The argument is passed as ANSI or Unicode respectively.
(fli:define-foreign-function (%get-drive-type "GetDriveType" :dbcs)
    ((lpRootPathName W:LPCTSTR))
    :result-type (:unsigned :int))


(defconstant +drive-types+
   #(:unknown :none :removable :fixed :remote :cdrom :ramdisk))


(defun get-drive-information (drive)
  (the drive-type (svref +drive-types+ (%get-drive-type drive))))



W:STR &key length
An ANSI string

W:LPCSTR  &key max-length
A reference-pass pointer to an ANSI string

W:LPSTR  &key max-length
A reference (in/out) pointer to an ANSI string

The above three types are ANSI only. Use these if you don't mind losing the power of Unicode on NT. Take care to interface to functions FooBarA.


W:WSTR &key length
An UNICODE string

W:LPCWSTR  &key max-length
A reference-pass pointer to an UNICODE string

W:LPWSTR  &key max-length
A reference (in/out) pointer to an UNICODE string

The above three types are UNICODE only. You are unlikely to need these unless you know your application only needs to run on NT, or if you are interfacing to some of the few 'W' functions that are available on W9x. In that case, you need to pass the correct function name, FooBarW, to DEFINE-FOREIGN-FUNCTION

See Also:
Workaround:
Patch:

Hardware:N/A
Summary:Win32 API and strings
Bug#:
Patch Enhancement#:
Reported:5312

Top | Back