Что касается API / библиотеки, обычно, если вам понадобится непрозрачная структура, вы не позволяете пользователю API объявлять такие вещи, как массивы или статические экземпляры, из-за этого. Не знать ничего о структуре - это название игры, поэтому вам, вероятно, придется определить некоторые функции для управления ими. Большинство библиотек C, которые объявляют непрозрачные структуры, часто имеют функции доступа и модификации.
Один из примеров от Lua (очевидно, что состояние Lua - это структура одноразового использования, но это идея):
typedef struct lua_State lua_State;
void lua_pushnumber(lua_State *s, lua_Number n);
В этом случае, если вы решили, что вам нужно несколько состояний Lua, вы должны сделать что-то вроде следующего:
lua_State *states[5];
for(int i = 0; i < 5; i++)
states[i] = lua_open();
Я думаю, что общее эмпирическое правило заключается в том, что если вы работаете с непрозрачными структурами, вы будете работать только с указателями, что в любом случае является практически единственным способом сделать это.