Альтернатива до R16B driver_async_port_key

Согласно документации erl_driver для driver_async_port_key функция,

До OTP-R16 фактический идентификатор порта мог использоваться в качестве ключа с надлежащим приведением, но после перезаписи подсистемы портов это уже не так. С помощью этой функции вы можете добиться того же распределения на основе идентификаторов портов, что и до OTP-R16.

Что это за правильный кастинг?

1 ответ

Решение

ErlDrvPort type - это typedef указателя на структуру. Чтобы получить unsigned int Асинхронный тип ключа в старых приложениях драйвера, вам нужно преобразовать этот тип указателя в unsigned int, Один из способов добиться этого - провести его через C99. uintptr_t тип, который гарантированно будет достаточно большим, чтобы содержать значение указателя:

#include <stdint.h>
#include "erl_driver.h"

unsigned int my_port_key(ErlDrvPort port)
{
    return (unsigned int) (uintptr_t) port;
}

Вы можете написать переносную функцию для возврата асинхронного ключа, используя информацию о версиях API драйвера, доступную в erl_driver.h, driver_async_port_key функция была введена в драйвере API версии 2.2, поэтому мы можем вызвать driver_async_port_key при использовании версии 2.2 или новее, или используйте метод приведения к более старым версиям:

#include <stdint.h>
#include "erl_driver.h"

unsigned int my_port_key(ErlDrvPort port)
{
#if ERL_DRV_EXTENDED_MAJOR_VERSION > 2 || \
    (ERL_DRV_EXTENDED_MAJOR_VERSION == 2 && ERL_DRV_EXTENDED_MINOR_VERSION >= 2)
    return driver_async_port_key(port);
#else
    return (unsigned int) (uintptr_t) port;
#endif
}
Другие вопросы по тегам