Разница в том, что имя массива неявно преобразуется в указатель на его первый элемент в большинстве ситуаций, тогда как имя объекта типа структуры не является.
Выражение pItem* pei = (pItem*)api;
будет компилироваться, потому чтооно эквивалентно pItem* pei = (pItem*)(&api[0]);
. Выражение pItem* pei = (pItem*)ei;
не будет компилироваться, поскольку оно пытается привести объект типа структуры (значение) к указателю на некоторый не связанный тип.
Выражение, которое вы использовали, pItem* pei = (pItem*)(&ei);
создает указатель на объект структуры и интерпретирует его как указатель на pItem.Поскольку pItem является первым элементом структуры, он расположен по тому же адресу памяти, что и ei
, и это работает.(это даже гарантируется стандартом, §6.7.2.1 / 13: «указатель на объект структуры, соответствующим образом преобразованный, указывает на его начальный член»)