[Haskell-cafe] Why am I not allowed to use CStringLen
inforeignexport?
Brian Hulley
brianh at metamilk.com
Fri Sep 15 16:07:25 EDT 2006
Brian Hulley wrote:
> I assume that this means that on 32 bit Windows, the format of a BSTR
> is:
> Word16 -- low word of length
> Word16 -- high word of length
> Word16 -- first char of string
> ...
The above is not quite correct. It appears from
http://www.oreilly.com/catalog/win32api/chapter/ch06.html that the length
must preceed the actual BSTR, thus you must give VBA a pointer to the first
*char* in the string not the actual start of the array of Word16's in
memory. Furthermore, it appears that a terminating NULL is still needed even
though the string itself can contain NULL characters. No only that, but the
length must be given as the number of *bytes* (excluding the terminating
NULL) not the number of characters.
Therefore here is a revised attempt at creating a Win32 BSTR:
import Data.Word
import Data.Bits
import Foreign.Marshal.Array
import Foreign.Ptr
type BSTR = Ptr Word16
createBSTR :: [Char] -> IO BSTR
createBSTR s = do
let
len :: Word32 = fromIntegral (length s * 2)
low :: Word16 = fromIntegral (len .&. 0xFFFF)
high :: Word16 = fromIntegral (shiftR len 16 .&. 0xFFFF)
arr <- newArray ([low, high] ++ map (fromIntegral . fromEnum) s ++
[0])
return $! plusPtr arr 4
foreign export stdcall hello :: IO BSTR
hello :: IO BSTR
hello = createBSTR "Hello world!"
Regards, Brian.
More information about the Haskell-Cafe
mailing list