memcpy 指向字符缓冲区的指针

memcpy a pointer to a char buffer

我目前正在试验 Job 系统的一些不同实现(基于 this 文章)。

我要解决的问题是将参数传递给 "Job function"。

这是我的 Job 定义:

#define JOB_DATA_PADDING_SIZE   44

/** A job function is a function that can be worked on by the job manager */
typedef void( *JobFunction )( struct Job*, const void* );

/// <summary>
/// A job is something that represents work to be done by the thread pool.
/// Contains a pointer to it's work function and a counter to how many jobs
/// still need to be completed.
/// </summary>
struct Job
{
    JobFunction Function;                       // 8 byte
    Job* Parent;                                // 8 byte
    std::atomic<int32_t> UnfinishedJobs;        // 4 byte
    char Padding[ JOB_DATA_PADDING_SIZE ];      // 44 bytes, so that this object fills
                                                // a whole x64 cache line
};

如您所见,char Padding 缓冲区需要存在以避免错误共享。我想使用该缓冲区作为一种简单地存储需要传递给用户正在调用的 JobFunction 的参数的方法。此设置运行良好,但有一个例外:将指针作为参数传递。

当用户去创建工作时,他们在 JobManager:

上调用这个函数
Job * JobManager::CreateJob( JobFunction aFunction, void* args, size_t aSize )
{
    assert( aSize >= 0 && aSize < JOB_DATA_PADDING_SIZE );

    Job* job = AllocateJob();
    job->Function = aFunction;
    job->Parent = nullptr;
    job->UnfinishedJobs.store( 1 );

    // Memcpy the args to the jobs padding
    if ( args != nullptr )
    {
        memcpy( job->Padding, args, aSize );
    }

    return job;
}

如您所见,计划只是将用户提供给函数的参数 memcpy 放入 Padding 中。这适用于结构之类的东西,实际上任何小于 44 字节大小的数据。

我想要做的是 memcpy 一个给定的指针 进入 那个 Padding 数组。但是,当我尝试这个时,我 运行 遇到了 memcpy 复制指针值并将其复制到缓冲区的问题。

有没有办法可以 memcpy 将实际的 指针 放入缓冲区?

我尝试过 uint64_tuintptr_t 但无济于事。

有办法吗?我对这应该如何工作完全错了吗?

整个项目都在 GitHub 上,如果这也有助于提供更多背景信息的话。

Is there a way that I can memcpy the actual pointer into the buffer?

当然可以。 Memcpy 不关心它复制的是什么。它所做的只是将字节从源位置复制到目标位置。

假设您要复制一个 int 值。 Memcpy 不知道 int 值。它只知道 个位置 。因此,您必须将值放入某个内存位置(例如,放入 int 变量 ),然后您可以为 memcpy 提供指向它的指针。

extern void* destination_pointer;
int source = getIntValueFromWherever();          // put the value into the source location
size_t n_bytes = sizeof(source);
memcpy(destination_pointer, &source, n_bytes);   // then give memcpy a pointer to it.

但是你想复制一个指针。好吧,这是一样的交易。你想要复制的东西(例如,一些 foobar_t* 指针)必须存储在一个位置(例如,在一个变量中)。然后你给 memcpy 指向源和目标位置的指针。

与上面的int示例唯一不同的是source变量的数据类型:

extern void* destination_pointer;
foobar_t* source = getPointerFromWherever();     // put the value into the source location
size_t n_bytes = sizeof(source);
memcpy(destination_pointer, &source, n_bytes);   // then give memcpy a pointer to it.