winsock2/ws2_32 issues

46 views
Skip to first unread message

Oliver Palmer

unread,
Jun 11, 2016, 4:12:58 PM6/11/16
to pytho...@googlegroups.com
Hi,

I've been using cffi on a project called pywincffi.  So far, cffi has been awesome and generally speaking has been a nice alternative to building C-extensions or using ctypes.  But I recently started trying to implement some functions from the winsock2/ws2_32 library and I'm starting to have some problems with the build.  I'm not certain if it's a problem on my part, a bug in cffi or none of the above so I'd like some help.  Here's the simplified code that I'm trying to get working:

    import cffi

    ffi = cffi.FFI()
    ffi.set_unicode(True)
    ffi.set_source("test", """
    #include <winsock2.h>
    #include <windows.h>
    """, libraries=("ws2_32", ))

    ffi.cdef("""
    int WSACreateEvent(SOCKET, WSAEVENT, long);
    """)

    ffi.compile()


This code, which does not use winsock2/ws2_32, will compile:

    import cffi

    ffi = cffi.FFI()
    ffi.set_unicode(True)
    ffi.set_source("test", """
    #include <windows.h>
    """, libraries=("kernel32", ))

    ffi.cdef("""
    typedef struct _SECURITY_ATTRIBUTES {
        DWORD  nLength;
        LPVOID lpSecurityDescriptor;
        BOOL   bInheritHandle;
    } SECURITY_ATTRIBUTES, *PSECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES;

    HANDLE CreateEvent(LPSECURITY_ATTRIBUTES, BOOL, BOOL, LPCTSTR);
    """)

    ffi.compile()

To my understanding, ffi.cdef() is called before the compiler so if there's a type cffi can't find and it's not declared with a typedef then it will result in an error at before calling compile().  With this assumption I tried this instead and it works:

    import cffi
    
    ffi = cffi.FFI()
    ffi.set_unicode(True)
    ffi.set_source("test", """
    #include <winsock2.h>
    #include <windows.h>
    """, libraries=("ws2_32", ))
    
    ffi.cdef("""
    int WSAEventSelect(unsigned int, HANDLE, long);
    """)
    
    ffi.compile()


So my question is, is there any way to get the first example to work or is there something else I'm missing.  I could use the code above I suppose but I'd rather make sure there's not something I'm missing first.

Thanks,
Oliver

Armin Rigo

unread,
Jun 12, 2016, 10:00:58 AM6/12/16
to pytho...@googlegroups.com
Hi Olivier,

On 11 June 2016 at 22:12, Oliver Palmer <oliver...@opalmer.com> wrote:
> ffi.cdef("""
> int WSACreateEvent(SOCKET, WSAEVENT, long);
> """)

CFFI itself only automatically knows about the "standard" C types.
CFFI must "know" about a type before you can use it in either cdef()
or in the main program (e.g. in ffi.new()). On Windows, the list of
known types includes all types from <windows.h>
(see https://bitbucket.org/cffi/cffi/raw/default/c/commontypes.c ).
This list doesn't include SOCKET or WSAEVENT from <winsock2.h>.
That's why cffi cannot parse the line above.

You need to say that SOCKET and WSAEVENT are types and approximately
what they are. For example, using partial declarations with the
dot-dot-dot syntax, and using the fact that HANDLE is predeclared (it
is from windows.h):

ffi.cdef("""
typedef int... SOCKET; /* some integer type */
typedef HANDLE WSAEVENT; /* according to winsock2.h */
int WSACreateEvent(SOCKET, WSAEVENT, long);
""")

It gives essentially the same declaration as the one you propose, but
it is more official. It uses the types that are originally from
<winsock2.h>, after you explain to CFFI what they are. After such a
cdef(), you can use in the main program the types SOCKET and WSAEVENT
directly too.


A bientôt,

Armin.

Oliver Palmer

unread,
Jun 14, 2016, 10:55:45 PM6/14/16
to python-cffi, ar...@tunes.org
Alright, thanks Armin for the help that makes sense.  I might submit a PR to add the extra types to commontypes.c once this project is closer to completion (I might discover a few more between now and then).

Armin Rigo

unread,
Jun 15, 2016, 3:29:45 AM6/15/16
to Oliver Palmer, python-cffi
Hi Oliver,

On 15 June 2016 at 04:55, Oliver Palmer <oliver...@opalmer.com> wrote:
> Alright, thanks Armin for the help that makes sense. I might submit a PR to
> add the extra types to commontypes.c once this project is closer to
> completion (I might discover a few more between now and then).

I don't add some random subset of types. I defined all the types from
Windows.h because most Windows programs include that file; for custom
headers you can define the types you use in the cdef(). Now
winsock2.h is probably important and standard enough that it might go
in the first category. If you think so, then we need to add
systematically *all* the types its documentation mentions.


A bientôt,

Armin.

Oliver Palmer

unread,
Jun 18, 2016, 12:47:05 PM6/18/16
to Armin Rigo, python-cffi
 If you think so, then we need to add systematically *all* the types its documentation mentions.

That would be the plan.  Soon after sending my reply I realized that adding only a subset for my use case is probably worse than just not including the typedefs at all from a consumer's standpoint....

Anyway, thanks again for the help.
Reply all
Reply to author
Forward
0 new messages