Zero-length arrays & Rust FFI


#1

Hello,

I’m trying to understand how to use C structs with zero-length arrays in Rust.

E.g. consider a struct dirent_t (a directory entry), which is defined as follows in Solaris-like operating systems:

typedef struct dirent {
  ino_t           d_ino;          /* "inode number" of entry */
  off_t           d_off;          /* offset of disk directory entry */
  unsigned short  d_reclen;       /* length of this record */
  char            d_name[1];      /* name of file */
} dirent_t;

Notice the last field, d_name: although it’s of length 1 in the struct, it’s actually dynamically allocated and of undefined length.

The same problem was posed on /r/rust, but this topic is one year old, where @brson commented:

The way C treats the final array field of a struct is very similar to how Rust will after DST.
I don’t think this works today.

So I’m guessing, is there a way to use DSTs with FFI now?


#2

Well, usually you can use DST with structs by putting the DST as the last field. But I’m not exactly sure what the right way to do the thing is here, to be honest.


#3

Hi,

I ran into a similar problem a while ago when rewriting some of my C code for Windows. The problem was that I needed to fill out a BITMAPINFO info struct

https://msdn.microsoft.com/en-us/library/windows/desktop/dd183375(v=vs.85).aspx that looks like this

typedef struct tagBITMAPINFO {
  BITMAPINFOHEADER bmiHeader;
  RGBQUAD          bmiColors[1];
} BITMAPINFO, *PBITMAPINFO;

Here the bmiColors[1] is of dynamic size. So my work-around was to do like this (I only needed to fill out the 3 firs entries)

And then use this structure further down in the code instead of the regular BITMAPINFO struct.

I’m not sure if this helps you at all but I wanted write about it at least.