[Haskell-cafe] Why am I not allowed to use CStringLen
Andreas-Haskell at gmx.net
Fri Sep 22 03:53:19 EDT 2006
Thanks a lot for this information it helped a lot.
Because I use the VBA 6 version the string characters are supposed to be a
byte so I changed your code to
type BSTR8 = Ptr Word8
createBSTR8 :: String -> IO BSTR8
createBSTR8 s = do
len :: Word32 = fromIntegral (length s)
low_l :: Word8 = fromIntegral (len .&. 0xFFFF)
low_h :: Word8 = fromIntegral (shiftR len 8 .&. 0xFFFF)
high_l :: Word8 = fromIntegral (shiftR len 16 .&. 0xFFFF)
high_h :: Word8 = fromIntegral (shiftR len 24 .&. 0xFFFF)
arr <- newArray ([low_l,low_h,high_l,high_h] ++ map (fromIntegral .
fromEnum) s ++ )
return $! plusPtr arr 4
Maybe this helps some one else too.
I am thinking about creating a wikipage about Haskell<->VBA interfacing
through a DLL.
Is it okay for you if I put your code there?
I am a bit concerned about the memory. newArray states that the memory has
to be freed after usage. Is this needed here? How can it be done?
Thanks to everyone who responded,
----- Original Message -----
From: "Brian Hulley" <brianh at metamilk.com>
To: "Andreas Marth" <Andreas-Haskell at gmx.net>; <haskell-cafe at haskell.org>
Sent: Friday, September 15, 2006 10:07 PM
Subject: Re: [Haskell-cafe] Why am I not allowed to use CStringLen
> 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
> *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
> though the string itself can contain NULL characters. No only that, but
> 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
> 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 ++
> 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