Сишный подход к приватным полям выглядит так: ты для себя и для клиента делаешь разные хидеры. В хидере клиента ты пропускаешь несколько последних полей (можешь хоть вообще пустую структуру объявить). В своём хидере указываешь все поля.
Если клиент создаёт и удаляет структуру только через твои функции и только на куче, то это сработает.