Соображения языка C++

Поскольку Ваш драйвер будет, вероятно, записан как комбинация C и кода C++, существуют некоторые потенциальные ловушки, которых необходимо попытаться избежать. Многие из них описаны в этой главе.

Набор I/O в целом записан в подмножестве C++. Следующие функции не позволяются:

Для получения дополнительной информации см. Основные принципы IOKit и раздел Object Creation и Destruction Руководства по проектированию Драйвера устройства IOKit.

Различия в размере типа данных

Одна из наиболее распространенных ошибок при портировании ядра драйвера C на Набор I/O предполагает, что тип данных в C будет иметь тот же размер как тип данных с аналогичным именем в C++. Это не всегда имеет место.

Хорошее правило состоит в том, чтобы всегда удостоверяться, что Вы используете точно тот же тип данных (с тем же именем) с обеих сторон когда передающие данные между C и частями C++ Вашего драйвера. Это может спасти Вас много головных болей и ненужной отладки в будущем.

Обработка C к обратным вызовам C++

C код не может вызвать методы класса непосредственно. Это излагает что-то вроде проблемы, если Вы пишете код, куда метод C++ должен быть передан как обратный вызов в Ваш базовый код C.

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

Соблюдающие правила должны сопровождаться:

Например, Вы могли бы записать функцию ретрансляции, которая похожа на это:

static int org_mklinux_iokit_swim3_driver_dosomething(
    org_mklinux_iokit_swim3_driver *self, int something_arg)
{
    dIOLog(DEBUG_GENERAL, "dosomething: enter (0x%x)\n",
        (unsigned int)self);
 
    self->dosomething(something_arg);
}

Для Вашего обратного вызова необходимо было бы передать две вещи в базовый код C: адрес экземпляра класса (значение this указатель), и адрес этой функции. После этого код C может вызвать функцию класса dosomething путем выполнения чего-то вроде этого:

ret = (*funcptr)(classptr, argument);

где funcptr указатель на функцию ретрансляции, classptr указатель на экземпляр класса чей dosomething метод нужно вызвать, и argument параметр, который будет передан dosomething метод.