On Aug 31 2015, Stefan Behnel <
stef...@behnel.de> wrote:
> [....]
Ok, so if I understand correctly, you're proposing something like this:
,----
| cdef extern from *:
| const_char* TARGET_PLATFORM
|
| cdef extern from "fuse_lowlevel.h" nogil:
| struct fuse_lowlevel_ops:
| void (*init) (void *userdata, fuse_conn_info *conn)
|
| # Not valid for Darwin
| void (*setxattr)(fuse_req_t req, fuse_ino_t ino, const_char *name,
| const_char *value, size_t size, int flags)
|
|
| cdef void fuse_setattr (fuse_req_t req, fuse_ino_t ino, struct_stat *stat,
| int to_set, fuse_file_info *fi) with gil:
| # code
|
|
| cdef void fuse_setxattr_darwin (fuse_req_t req, fuse_ino_t ino, const_char *cname,
| const_char *cvalue, size_t size, int flags,
| uint32_t position) with gil:
| # code
|
|
| cdef void init_fuse_ops(fuse_lowlevel_ops* fuse_ops):
| '''Initialize fuse_lowlevel_ops structure'''
|
| string.memset(fuse_ops, 0, sizeof(fuse_lowlevel_ops))
| fuse_ops.init = fuse_init
| if TARGET_PLATFORM == 'darwin':
| fuse_ops.setxattr = <void*> fuse_setxattr_darwin
| else:
| fuse_ops.setxattr = <void*> fuse_setxattr
`----
which I would then compile with -DTARGET_PLATFORM=darwin or
-DTARGET_PLATFORM=linux.
Did I understand you correctly?
This would have the advantage that I no longer have to use undocumented
APIs to set TARGET_PLATFORM in Cython, but it has the drawback that if I
make an error in the signature of fuse_setxattr_darwin, neither Cython
nor the C compiler would be able to detect it.
So is this really an improvement over what I'm doing at the moment?
I don't think I can cast to the actual type of fuse_ops.setxattr instead
of void*. Fuse_lowlevel.h doesn't export it as a separate
ctypedef, so I would need to do either:
| if TARGET_PLATFORM == 'darwin':
| fuse_ops.setxattr = <void (*setxattr)(fuse_req_t, fuse_ino_t, const_char*,
| const_char*, size_t, int)> fuse_setxattr_darwin
| # ...
..in which case the C compiler will give a type error under darwin (I'm
casting to the wrong type), or
| if TARGET_PLATFORM == 'darwin':
| fuse_ops.setxattr = <void (*setxattr)(fuse_req_t, fuse_ino_t, const_char*,
| const_char*, size_t, int, uint32_t)> fuse_setxattr_darwin
| # ...
..in which case Cython will give a type error.
Don't get me wrong, I actually agree that generating a single C file for
all platforms would be a much better solution. But looking at the
practical implications, they fall a bit short of my expectations. But
maybe (hopefully) I'm just still not doing it right.