Альтернативы директивам препроцессору

array_count_values() возвращает список значений и количество раз, которое они встречаются, поэтому простое использование array_push() добавит весь этот массив как 1 элемент и даст вам результаты, которые вы получили.

Вместо этого вы можете добавлять результаты по одному в массив $temp и получать результаты после ...

$temp = [];
$res = array_count_values(array_column($query, 'status'));
foreach ( $res as $key=>$item )   {
    $temp[] = [$key => $item];
}
print_r(json_encode($temp));
6
задан Brian Tompsett - 汤莱恩 4 June 2016 в 17:41
поделиться

9 ответов

Я был именно там, где вы.

Одна уловка в том, что даже если у вас будут условия в коде, не включайте версии для Symbian. Это затрудняет добавление поддержки новых версий в будущем или настройку телефонов, которые в чем-то необычны. Вместо этого определите, на какие фактические свойства вы полагаетесь, напишите код вокруг них, а затем включите файл заголовка, который выполняет:

#if S60_3rd_ED
    #define CAF_AGENT 1
    #define HTTP_FILE_UPLOAD 1
#elif S60_2nd_ED
    #define CAF_AGENT 0
    #if S60_2nd_ED_FP2
        #define HTTP_FILE_UPLOAD 1
    #else
        #define HTTP_FILE_UPLOAD 0
    #endif
#endif

и так далее. Очевидно, что вы можете сгруппировать определения по функциям, а не по версиям, если хотите, иметь совершенно разные заголовки для каждой конфигурации или любую другую схему, которая вам подходит.

У нас есть определения для классов пользовательского интерфейса, от которых вы наследуете, так что были некоторые Общий код пользовательского интерфейса между S60 и UIQ. Фактически, из-за того, чем был продукт, у нас не было много кода, связанного с пользовательским интерфейсом,

[Изменить в ответ на комментарий:

Мы очень старались не делать что-либо, зависящее от разрешения - к счастью, конкретное приложение не сделало это слишком сложным, поэтому наш ограниченный пользовательский интерфейс был довольно общим. Главное, где мы включили разрешение экрана, было для заставок / фоновых изображений и тому подобного. У нас был сценарий для предварительной обработки файлов сборки, который подставлял ширину и высоту в имя файла, splash_240x320.bmp или что-то еще. На самом деле мы сгенерировали изображения вручную, так как их было не так много разных размеров и изображения менялись нечасто. Тот же сценарий создал файл .h, содержащий #defines большинства значений, используемых при создании файла сборки.

Это для сборок для каждого устройства: у нас также были более общие файлы SIS, которые просто изменяли размер изображений на лету, но у нас часто были требования к установленному размеру (ПЗУ иногда было довольно ограниченным, что имеет значение, если ваше приложение является частью базового образа устройства), и изменение размера изображений было одним из способов немного уменьшить его. Для поддержки поворота экрана на N92, Z8 и т. Д. Нам по-прежнему нужны были портретные и альбомные версии некоторых изображений, поскольку изменение соотношения сторон не дает таких хороших результатов, как изменение размера до того же или подобного соотношения ...]

5
ответ дан 8 December 2019 в 03:11
поделиться

Ну ... Это зависит от точного характера различий. Если возможно их абстрагировать и изолировать в определенные классы, вы можете пойти по этому пути. Это означало бы наличие специфичных для версии реализаций некоторых классов и переключение целых реализаций, а не просто нескольких строк здесь и там.

У вас будет

  • MyClass.h
  • MyClass_S60_2nd.cpp
  • MyClass_S60_3rd. cpp

и так далее. Вы можете выбрать, какой файл CPP компилировать, либо заключив его внутрь с помощью #ifdefs, как указано выше, либо я контролирую на уровне сборки (через Makefiles или что-то еще), какие файлы включаются при сборке для различных целей.

В зависимости от характера изменений это может быть намного чище.

16
ответ дан 8 December 2019 в 03:11
поделиться

Look at SQLite. They have the same problem. They move the platform-dependent stuff to separate files and effectively compile only needed stuff by having the preprocessor directives that exclude an entire file contents. It's a widely used approach.

1
ответ дан 8 December 2019 в 03:11
поделиться

В нашей компании мы пишем много кроссплатформенного кода (разработка игр для win32 / ps3 / xbox / и т. Д.).
Чтобы избежать макросов, связанных с платформой, насколько это возможно, мы обычно используем следующие несколько приемов:

  • извлечение кода, связанного с платформой, в библиотеки абстракции платформы, которые имеют одинаковый интерфейс на разных платформах, но не одинаковую реализацию;
  • split код в разные файлы .cpp для разных платформ (например: «pipe.h», «pipe_common.cpp», «pipe_linux.cpp», «pipe_win32.cpp», ...);
  • используйте макросы и вспомогательные функции для унифицировать вызовы функций, специфичных для платформы (например: «#define usleep (X) Sleep ((X) / 1000u)»);
  • использовать межплатформенные сторонние библиотеки.
6
ответ дан 8 December 2019 в 03:11
поделиться

Вы можете попробовать определить общий интерфейс для всех платформ, если это возможно. Затем реализуйте интерфейс для каждой платформы.

Выберите правильную реализацию с помощью директив препроцессора.

Таким образом, у вас будет директива выбора платформы в меньшем количестве мест в вашем коде (в идеале, в одном месте, явно в заголовке файл, объявляющий интерфейс).

Это означает что-то вроде:

commoninterface.h /* declaring the common interface API. Platform identification preprocessor directives might be needed for things like common type definitions */
platform1.c /*specific implementation*/
platform2.c /*specific implementation*/
1
ответ дан 8 December 2019 в 03:11
поделиться

There are several differences between S60 2nd ed and 3rd ed applications that are not limited to code: application resource files differ, graphic formats and tools to pack them are different, mmp-files differ in many ways.

Based on my experience, don't try to automate it too much, but have a separate build scripts for 2nd ed and 3rd ed. In code level, separate differences to own classes that have common abstract API, use flags only in rare cases.

1
ответ дан 8 December 2019 в 03:11
поделиться

Нет идей по поводу альтернативы, но что вы можете сделать, так это использовать разные файлы для включения в разные версии ОС. пример

#ifdef S60_2nd_ED

#include "graphics2"

#elif S60_3rd_ED

#include "graphics3"

#else

#include "graphics"

0
ответ дан 8 December 2019 в 03:11
поделиться

You could something like they do for the assembly definition in the linux kernel. Each architecture has its own directory (asm-x86 for instance). All these folders cluster the same high level header files presenting the same interface. When the kernel is configured, a link named asm is created targeting the appropriate asm-arch directory. This way, all the C files include files like .

0
ответ дан 8 December 2019 в 03:11
поделиться

Вам следует избегать распространения #if через код.

Скорее; используйте #if в файлах заголовков для определения альтернативных макросов, а затем в коде используйте единственный макрос.

Этот метод позволяет сделать код более читабельным.

Пример:

 Plop.h
 ======

 #if V1
 #define    MAKE_CALL(X,Y)    makeCallV1(X,Y)
 #elif V2
 #define    MAKE_CALL(X,Y)    makeCallV2("Plop",X,222,Y)
 ....
 #endif


 Plop.cpp
 ========

 if (pushPlop)
 {
     MAKE_CALL(911,"Help");
 }

Чтобы упростить разделение кода конкретной версии на свои собственные функции, затем используйте макросы для активации функций, как показано выше. Также вы можете обернуть изменяющиеся части SDK в свой собственный класс, чтобы попытаться обеспечить согласованный интерфейс, тогда все ваши различия будут управляться внутри класса оболочки, оставив ваш код, который делает работу более аккуратной.

0
ответ дан 8 December 2019 в 03:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: