This package allows easy conversion between null terminated BSTRs and Ada supported types. It should be noted, that it is not possible to create/use non-null terminated BSTRs with this example.
with Win32.OleAuto; with Interfaces.C; package BSTR is -- These conversion functions create a new BSTR that requires a Free -- to destroy function To_BSTR( From_Ada : Wide_String ) return Win32.OleAuto.BSTR; function To_BSTR( From_Ada : String ) return Win32.OleAuto.BSTR; function To_BSTR( From_C : Interfaces.C.WChar_Array ) return Win32.OleAuto.BSTR; function To_BSTR( From_C : Interfaces.C.Char_Array ) return Win32.OleAuto.BSTR; -- These conversion functions do not destroy the original BSTR function To_Ada( From_BSTR : Win32.OleAuto.BSTR ) return Wide_String; function To_Ada( From_BSTR : Win32.OleAuto.BSTR ) return String; function To_C( From_BSTR : Win32.OleAuto.BSTR ) return Interfaces.C.WChar_Array; function To_C( From_BSTR : Win32.OleAuto.BSTR ) return Interfaces.C.Char_Array; -- This conversion can free BSTRs created with this packages conversion -- functions and those created with the Win32 API function SysAllocString procedure Free( This : Win32.OleAuto.BSTR ); BSTR_Error : exception; end BSTR; with Win32.Oleauto; use Win32.Oleauto; with Interfaces.C; use Interfaces.C; with Interfaces.C.Pointers; with Ada.Exceptions; with Ada.Characters.Handling; with Ada.Unchecked_Conversion; with System; package body BSTR is ------------------------------------------------------------------------------- -- Private ------------------------------------------------------------------------------- type PWChar_t is access all Interfaces.C.WChar_t; function To_PCWSTR is new Ada.Unchecked_Conversion (System.Address, Win32.PCWSTR); function To_PWChar_t is new Ada.Unchecked_Conversion (System.Address, PWChar_t); package WChar_Array_Pointer is new Interfaces.C.Pointers (index => Interfaces.C.Size_t, element => Interfaces.C.WChar_t, element_array => Interfaces.C.WChar_array, default_terminator => Interfaces.C.Wide_Nul); ------------------------------------------------------------------------------- -- Public ------------------------------------------------------------------------------- -- Create BSTR conversions function To_BSTR (From_Ada : Wide_String) return Win32.OleAuto.BSTR is begin return To_BSTR( Interfaces.C.To_C(From_Ada) ); end To_BSTR; function To_BSTR (From_Ada : String) return Win32.OleAuto.BSTR is begin return To_BSTR ( Interfaces.C.To_C( Ada.Characters.Handling.To_Wide_String(From_Ada) ) ); end To_BSTR; function To_BSTR (From_C : Interfaces.C.WChar_Array) return Win32.OleAuto.BSTR is New_BSTR : Win32.OleAuto.BSTR; begin New_BSTR := SysAllocString( To_PCWSTR( From_C'Address ) ); if New_BSTR = null then Ada.Exceptions.Raise_Exception(BSTR_Error'Identity, "BSTR - Unable to create BSTR"); end if; return New_BSTR; end To_BSTR; function To_BSTR (From_C : Interfaces.C.Char_Array) return Win32.OleAuto.BSTR is begin return To_BSTR ( Interfaces.C.To_C( Ada.Characters.Handling.To_Wide_String( Interfaces.C.To_Ada(From_C) ) ) ); end To_BSTR; -- Convert to Ada and C strings function To_Ada (From_BSTR : Win32.OleAuto.BSTR) return Wide_String is begin return Interfaces.C.To_Ada( To_C(From_BSTR) ); end To_Ada; function To_Ada (From_BSTR : Win32.OleAuto.BSTR) return String is begin return Ada.Characters.Handling.To_String( To_Ada (From_BSTR) ); end To_Ada; function To_C (From_BSTR : Win32.OleAuto.BSTR) return Interfaces.C.WChar_Array is begin return WChar_Array_Pointer.value (WChar_Array_Pointer.pointer (To_PWChar_t(From_BSTR.all'Address))); end To_C; function To_C (From_BSTR : Win32.OleAuto.BSTR) return Interfaces.C.Char_Array is begin return Interfaces.C.To_C( Ada.Characters.Handling.To_String( Interfaces.C.To_Ada( To_C(From_BSTR) ) ) ); end To_C; -- Destroy BSTRs procedure Free (This : Win32.OleAuto.BSTR) is begin SysFreeString(This); end Free; end BSTR;