ctypes NULL pointers; was: Python To Send Emails Via Outlook Express

Discussion in 'Python' started by Lenard Lindstrom, Jan 2, 2005.

  1. Posted in a previous thread was some Python code for accessing Window's
    Simple MAPI api using the ctypes module.

    http://groups-beta.google.com/group/comp.lang.python/msg/56fa74cdba9b7be9

    This Simple MAPI module was Ian's completed version of an example
    I had posted in an earlier message. In it I had to set some pointer
    fields in a C structure to NULL. I was not happy with the solution I
    used so I made an inquiry on the ctypes-users mailing list. Thanks to
    Thomas Heller I got some answers.

    The simplest way to create a NULL pointer instance in ctypes is to
    call the pointer class without an argument.

    from ctypes import POINTER, c_int
    INT_P = POINTER(c_int) # A pointer to a C integer
    p = INT_P() # An INT_P instance set to NULL

    When the pointer is a member of a structure things are a little different.
    For the ctypes primatives c_void_p, c_char_p and c_wchar_p one can simply
    use None to set the field NULL.

    from ctypes import Structure, c_void_p
    class STRUCT(Structure):
    _fields_ = [('voidptr', c_void_p)]
    s=STRUCT( None ) # Create an instance with voidptr field NULL

    This is documented in the ctypes tutorial. A problem with ctypes 0.9.2
    prevents using None to initialize POINTER derived fields. This has
    been fixed so future releases will allow it. In the meantime the
    following will work.

    class IPSTRUCT(Structure):
    _fields_ [('intptr'), INT_P]
    s=IPSTRUCT( INT_P() )

    A null pointer of the correct type is assigned to the field. I hope this
    clears up any confusion my Simple MAPI example may have caused regarding
    ctypes pointers.

    Lenard Lindstrom
    <>
     
    Lenard Lindstrom, Jan 2, 2005
    #1
    1. Advertising

  2. Lenard Lindstrom

    Guest

    Thanks again Lenard!!
     
    , Jan 2, 2005
    #2
    1. Advertising

  3. Ok ; thank you.
     
    Michel Claveau - abstraction méta-galactique non t, Jan 2, 2005
    #3
  4. Lenard Lindstrom

    Guest

    Hi Lenard
    Hopefully I have understood you properly.
    The updated script is now as follows, or you can download it from
    http://www.kirbyfooty.com/simplemapi.py
    Thanks again for all your help!!!

    Kindest regards
    Ian Cook


    --------------------------------------------------------------------------
    import os
    from ctypes import *

    FLAGS = c_ulong
    LHANDLE = c_ulong
    LPLHANDLE = POINTER(LHANDLE)


    # Return codes
    SUCCESS_SUCCESS = 0
    # Recipient class
    MAPI_ORIG = 0
    MAPI_TO = 1


    class STRUCT(Structure):
    _fields_ = [('voidptr', c_void_p)]
    #NULL = c_void_p(None)
    NULL=STRUCT( None ) # Create an instance with voidptr field NULL

    class MapiRecipDesc(Structure):
    _fields_ = [('ulReserved', c_ulong),
    ('ulRecipClass', c_ulong),
    ('lpszName', c_char_p),
    ('lpszAddress', c_char_p),
    ('ulEIDSize', c_ulong),
    ('lpEntryID', c_void_p),
    ]
    lpMapiRecipDesc = POINTER(MapiRecipDesc)


    class MapiFileDesc(Structure):
    _fields_ = [('ulReserved', c_ulong),
    ('flFlags', c_ulong),
    ('nPosition', c_ulong),
    ('lpszPathName', c_char_p),
    ('lpszFileName', c_char_p),
    ('lpFileType', c_void_p),
    ]
    lpMapiFileDesc = POINTER(MapiFileDesc)


    class MapiMessage(Structure):
    _fields_ = [('ulReserved', c_ulong),
    ('lpszSubject', c_char_p),
    ('lpszNoteText', c_char_p),
    ('lpszMessageType', c_char_p),
    ('lpszDateReceived', c_char_p),
    ('lpszConversationID', c_char_p),
    ('flFlags', FLAGS),
    ('lpOriginator', lpMapiRecipDesc), # ignored?
    ('nRecipCount', c_ulong),
    ('lpRecips', lpMapiRecipDesc),
    ('nFileCount', c_ulong),
    ('lpFiles', lpMapiFileDesc),
    ]
    lpMapiMessage = POINTER(MapiMessage)


    MAPI = windll.mapi32


    MAPISendMail=MAPI.MAPISendMail
    MAPISendMail.restype = c_ulong # Error code
    MAPISendMail.argtypes = (LHANDLE, # lhSession
    c_ulong, # ulUIParam
    lpMapiMessage, # lpMessage
    FLAGS, # lpFlags
    c_ulong, # ulReserved
    )


    def SendMail(recipient, subject, body, attachfiles):
    """Post an e-mail message using Simple MAPI
    Special thanks to Lenard Lindstrom!

    recipient - string: address to send to (multiple address sperated
    with a semicolin)
    subject - string: subject header
    body - string: message text
    attach - string: files to attach (multiple attachments sperated
    with a semicolin)

    Example usage
    import simplemapi

    simplemapi.SendMail(";","My
    Subject","My message body","c:\attachment1.txt;c:\attchment2")


    """

    # get list of file attachments
    attach = []
    AttachWork = attachfiles.split(';')

    #verify the attachment file exists
    for file in AttachWork:
    if os.path.exists(file):
    attach.append(file)


    attach = map( os.path.abspath, attach )
    nFileCount = len(attach)

    if attach:
    MapiFileDesc_A = MapiFileDesc * len(attach)
    fda = MapiFileDesc_A()
    for fd, fa in zip(fda, attach):
    fd.ulReserved = 0
    fd.flFlags = 0
    fd.nPosition = -1
    fd.lpszPathName = fa
    fd.lpszFileName = None
    fd.lpFileType = None
    lpFiles = fda
    else:
    # No attachments
    lpFiles = cast(NULL, lpMapiFileDesc) # Make NULL

    # Get the number of recipients
    RecipWork = recipient.split(';')
    RecipCnt = len(RecipWork)

    # Formulate the recipients
    MapiRecipDesc_A = MapiRecipDesc * len(RecipWork)
    rda = MapiRecipDesc_A()
    for rd, ra in zip(rda, RecipWork):
    rd.ulReserved = 0
    rd.ulRecipClass = MAPI_TO
    rd.lpszName = None
    rd.lpszAddress = ra
    rd.ulEIDSize = 0
    rd.lpEntryID = None
    recip = rda

    # send the message
    msg = MapiMessage(0, subject, body, None, None, None, 0,
    cast(NULL, lpMapiRecipDesc), RecipCnt, recip,
    nFileCount, lpFiles)


    rc = MAPISendMail(0, 0, byref(msg), 0, 0)
    if rc != SUCCESS_SUCCESS:
    raise WindowsError, "MAPI error %i" % rc

    --------------------------------------------------------------------------------
     
    , Jan 4, 2005
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Curt_C [MVP]
    Replies:
    0
    Views:
    603
    Curt_C [MVP]
    Apr 29, 2004
  2. Replies:
    2
    Views:
    766
    Toby Inkster
    Oct 13, 2005
  3. Replies:
    40
    Views:
    3,422
    Steve Holden
    Dec 27, 2004
  4. Andrew Thompson
    Replies:
    0
    Views:
    496
    Andrew Thompson
    Dec 7, 2006
  5. Jack
    Replies:
    5
    Views:
    432
Loading...

Share This Page