The FFI section of the Nomicon currently suggests to use an empty type for "opaque pointer types". That seems pretty dangerous. This came up in the discussion at rust-lang/rfcs#1861, and also in https://internals.rust-lang.org/t/recent-change-to-make-exhaustiveness-and-uninhabited-types-play-nicer-together/4602 many were not happy with using the empty type here.
Until we have proper opaque types, the safer suggestion seems to be do use a ZST with a private field, rather than an empty type. Then at least the type is not actively lying.