passing a file descriptor to a C library function

2020-05-28 05:02发布

问题:

I am trying to pass a file descriptor through ctypes, to a C function where writes are performed on the fd. On linux it works. On windows it doesn't and I don't understand why (I have no experience as a developer on windows)

//C func signature: 
void fun(struct bah *opaque, int fd)

from python (details ommited):

mylib.fun.argtypes = [POINTER(bah), c_int]
fh = open(filename,'wb')
#doesn't work on windows, works on linux/unix
mylib.fun(some_ctypes_struct, fh.fileno())
#doesn't work on windows
mylib.fun(bah_struct, ctypes.cdll.msvcrt._open(filename,_O_FLAGS_MASK, ACCMASK)
#doesn't work
mylib.fun(bah_struct, os.open(...))

program dies on write()s with a failed assertion _osfile(fh) & FOPEN

cl.exe: 16.00.40219.01 for x86 python 2.7.2 msc v.1500 32bit

how am I supposed to do it? no, I don't want to offload open() to lib. I want to pass an already open file descriptor in a safe manner, platform independent.


additional information, just in case: the library is tinycdb, I ported it quickly to windows with a short cmake spec and few dirty patches to make getopt and dll exports work. the library and the exe tool works as expected (tested). the python ctypes wrappers for tinycdb works on linux as expected. windows gives me eyeballs. he wont accept the fd is a valid descriptor even if I'm passing it after opening it with its own (msvcrt) _open libcall.


ofcourse, everything works if I'm open()ing/close()ing the file within the library but I can't afford to change the API.

回答1:

Windows doesn't use file descriptions like Unix does, so I'm hypothesizing that file descriptors are emulated by the C runtime. If you are using two different C runtimes (for example, if your EXE and DLL are compiled by different compilers, or with the same compiler but with different options), then each runtime will have its own "file descriptor emulation" and you can't pass a descriptor from one to the other.