Чтение общей памяти с x86 на x64 и наоборот на OSX - PullRequest
4 голосов
/ 24 октября 2011

Если я создаю SM из 64-разрядного приложения и открываю его в 32-разрядном приложении, это завершается ошибкой.

//for 64 bit
    shared_memory_object( create_only, "test" , read_write) ; 
// for 32 bit
    shared_memory_object (open_only, "test", read_write);
Файл

, созданный 64-битным приложением, находится по пути, указанному ниже:

/private/tmp/boost_interprocess/AD21A54E000000000000000000000000/test

, где 32-битное приложение ищет файл по пути

/private/tmp/boost_interprocess/AD21A54E00000000/test

Таким образом, 32-битные приложения не могут прочитать файл.

Я использую boost 1.47.0 на Mac OS X. Это ошибка? Нужно ли делать какие-то настройки, использовать несколько макросов, чтобы это исправить? Кто-нибудь сталкивался с этой проблемой раньше?

Ответы [ 2 ]

1 голос
/ 25 октября 2011

Я нашел решение проблемы и, как и ожидалось, это ошибка.

Эта ошибка присутствует в файле tmp_dir_helpers.hpp.

    inline void get_bootstamp(std::string &s, bool add = false)
    {
      ...
       std::size_t char_counter = 0;
       long  fields[2] = { result.tv_sec, result.tv_usec };
       for(std::size_t field = 0; field != 2; ++field){
          for(std::size_t i = 0; i != sizeof(long); ++i){
             const char *ptr = (const char *)&fields[field];
             bootstamp_str[char_counter++] = Characters[(ptr[i]&0xF0)>>4];
             bootstamp_str[char_counter++] = Characters[(ptr[i]&0x0F)];
          }
       ...
    }

Где, как и должно было бытьвот так ..

**long long** fields[2] = { result.tv_sec, result.tv_usec };
           for(std::size_t field = 0; field != 2; ++field){
              for(std::size_t i = 0; i != sizeof(**long long**); ++i)

Я создал тикет в бусте для этой ошибки.

Спасибо.

1 голос
/ 25 октября 2011

Важно ли, чтобы разделяемая память поддерживалась файлом? Если нет, вы можете рассмотреть возможность использования базовых API-интерфейсов разделяемой памяти Unix: shmget, shmat, shmdt и shmctl, все они объявлены в sys / shm.h. Я нашел их очень простыми в использовании.

// create some shared memory
int id = shmget(0x12345678, 1024 * 1024, IPC_CREAT | 0666);

if (id >= 0)
{
    void* p = shmat(id, 0, 0);

    if (p != (void*)-1)
    {
        initialize_shared_memory(p);

        // detach from the shared memory when we are done;
        // it will still exist, waiting for another process to access it
        shmdt(p);
    }
    else
    {
        handle_error();
    }
}
else
{
    handle_error();
}

Другой процесс будет использовать что-то вроде этого для доступа к общей памяти:

// access the shared memory
int id = shmget(0x12345678, 0, 0);

if (id >= 0)
{
    // find out how big it is
    struct shmid_ds info = { { 0 } };

    if (shmctl(id, IPC_STAT, &info) == 0)
        printf("%d bytes of shared memory\n", (int)info.shm_segsz);
    else
        handle_error();

    // get its address
    void* p = shmat(id, 0, 0);

    if (p != (void*)-1)
    {
        do_something(p);

        // detach from the shared memory; it still exists, but we can't get to it
        shmdt(p);
    }
    else
    {
        handle_error();
    }
}
else
{
    handle_error();
}

Затем, когда все процессы будут выполнены с общей памятью, используйте shmctl(id, IPC_RMID, 0), чтобы вернуть ее в систему.

Вы можете использовать инструменты ipcs и ipcrm в командной строке для управления общей памятью. Они полезны для устранения ошибок при первом написании кода общей памяти.

Несмотря на это, я не уверен в совместном использовании памяти между 32-битными и 64-битными программами. Я рекомендую попробовать API Unix, и если они потерпят неудачу, это, вероятно, не может быть сделано. В конце концов, именно они используют Boost в своей реализации.

...