forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   C++ (http://forum.boolean.name/forumdisplay.php?f=22)
-   -   Dog tag (http://forum.boolean.name/showthread.php?t=19085)

mr.DIMAS 08.04.2014 21:30

Dog tag
 
Привет пекари. Юзает ли кто-нибудь следующий прием в интерфейсах в своим либам?

Имеем структуру

Код:

struct Object

    int somethingUseful;
    ....
    int somethingUseful_n;
};

И хотим передать на вызывающую сторону этот объект. Передать объект из проги на С\С++ в другую прогу на С\С++ не проблема. Но если делаем библу под другие языки возможности передать структуру нет. Как быть? Передаем такую байду

Код:

int CreateObject()
{
    Object * obj = new Object;

    ...

    return reinterpret_cast<int>( obj );
}

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

Код:

void DoSomething( int object )
{
    Object * obj = reinterpret_cast<Object*>( object );

    // do something useful
}

И вот тут вырисовывается жирный минус этого подхода: нет гарантии того что "object" реально указатель на Object. Как быть?

Таки есть простой способ проверки правильности объекта.

Обновляем нашу структуру.

Код:

struct Object

    volatile int dogTag;

    int somethingUseful;
    ....
    int somethingUseful_n;
};

volatile нужен чтобы компилятор не баловался с этой переменной во время оптимизации.
Правим создание объекта
Код:

#define DOG_TAG ( 0xDEADBEEF )

int CreateObject()
{
    Object * obj = new Object;

    obj->dogTag = DOG_TAG;
    ...

    return reinterpret_cast<int>( obj );
}

Ну и нашу функцию делающую что-то с объектом.
Код:

void DoSomething( int object )
{
    Object * obj = GetObjectByHandle( object );


    // do something useful
}

Где GetObjectByHandle( object )
Код:

Object * GetObjectByHandle( int object )
{
    Object * obj = reinterpret_cast<Object*>(object);
   
    if( obj->dogTag == DOG_TAG )
      return obj;
 
    return 0;
}

В итоге не нужно создавать кэш всех объектов. Проверка dogTag простой способ проверки валидности объекта.

Пинайте ногами сей метод. :-D

Samodelkin 08.04.2014 21:47

Ответ: Dog tag
 
Да уж попинать надо.
Это на костыль похоже.

Для межпроцессного взаимодействия используют возможности ос.
Наверняка по PID можно удостовериться в валидности самого процесса.
А чтобы удостовериться в валидности объекта нужно просто вызывать функцию, которая возвращает только этот тип объекта.
О вызовах самих функций нужно договориться, но лучше stdcall, так как это совпадает с winapi (раз win делается?).

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

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

mr.DIMAS 08.04.2014 23:13

Ответ: Dog tag
 
Ок. Сужу поле действий: самопальная библа подключаемая к б3д. Как быть в таком случае?

HolyDel 09.04.2014 00:21

Ответ: Dog tag
 
Цитата:

Ок. Сужу поле действий: самопальная библа подключаемая к б3д. Как быть в таком случае?
все нормально. отправляй как есть.
попробуй в какой нибудь FreeEntity передать мусор.

ну если уж совсем запарываться - то делай set на указатель. при создании объекта указатель в set пуляй, при удалении изымай, при обращении проверяй.

mr.DIMAS 09.04.2014 00:52

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

Samodelkin 09.04.2014 01:48

Ответ: Dog tag
 
Я думаю у Xors3D есть определенный опыт взаимодействия нативного кода с блицем - посмотри как там.

Во первых твою задачу нужно чётко разделять на межпроцессное взаимодействие и на взаимодействие в одном адресном пространстве.
Второе решается проще.

Недостаток твоего подхода:
а) Неудобство пользователя: ты его опускаешь до уровня Си. Если ты не сопроводишь хедером с тегами, то пользователю придется самому писать эти теги, по памяти, так что легко ошибиться.
б) Проблема отладки: ты просто передаешь набор байтов без какой либо дополнительной информации. К тому же передача происходит чтением/записью - что не является каким либо структурным разделением выполняемой программы. Если бы ты использовал функцию и Соглашение о вызовах, дебарег смог бы хотя бы построить фреймы на основе стека и как либо структурировать действия программы. Более того если язык у клиента и библиотеки одинаковый, то я щитаю кощунство не использовать хедер с сигнатурами функций, описанием классов и т.п. потому что это тебе дает возможность отлаживать уже на уровне этого языка, а не ассемблера и компилятор сможет проконтролировать кучу ошибок и обезопасить код.
в) Проблема платформы: вот представь что ты скомпилировал библиотеку где выравнивание по 16 байтам, а у твоего объекта 4 байтные поля, а клиент скомпилирован с 4 байтным выравниванием, в итогде будут неприятности. Если был бы хедер то можно было бы хотябы при описании класса указать как выравнивать. А если были бы функции то вообще не было бы проблем - там оговорено как располагать в стеке или в каких регистрах.
г) Проблема защищенности: ты передаешь непонятно что, а если это является объектом то теоретически еще и методы переданного объекта можно вызывать. Представь себе если ктонибудь подделает тег, перепишет метод, например джампом вызовет вредоносный код и всё испортит тебе в системе. Так что тут не обойтись без протокола который обеспечивает минимальную защиту.

mr.DIMAS 09.04.2014 12:04

Ответ: Dog tag
 
Возможно я неправильно объяснил свою мысль в первом посте. Суть в том что пользователю библы мы отдаем только хендл объекта. А при передаче этого хендла обратно в библу нужно проверить - годен ли хендл. Для этого в каждой структуре есть определенная метка имеющая уникальное значение.

Вкратце: любая порождающая функция библы передает хендл. Остальные - принимают его с проверкой.

А вообще есть статья на эту тему


Часовой пояс GMT +4, время: 04:40.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot