如何在 DLL 中的 TThread 和主线程之间共享数据?

How to share data between a TThread in a DLL and the main thread?

我正在用 C++Builder XE6 编写一个 DLL,它创建一个单独的线程(从 TThread 派生)每隔 X 秒(使用 TIdHTTP)从 REST 服务器检索 JSON 数据,并解析JSON 数据。

线程在线程的 Execute() 方法中用解析的 JSON 数据填充一个简单的结构(没有动态分配的数据):

typedef struct
{
    char MyString[40 + 1];
    double MyDouble;
    bool MyBool;
} TMyStruct;

线程应将结构存储在列表中,例如 std::vector:

#include <vector>

std::vector<TMyStruct> MyList;

该线程将向列表中添加一个 TMyStruct:

TMyStruct Data;
...
MyList.push_back(Data);

列表将由 TCriticalSection 保护以防止数据损坏。

DLL 导出函数以从 MyList.

检索 TMyStruct
bool __declspec(dllexport) __stdcall GetMyStruct (int Index, TMyStruct* Data)
{
    ...
}

唯一的问题是,我不知道放在哪里MyList...

如果我让MyList成为一个全局变量,它位于主线程的内存中,GetMyStruct()可以直接访问它。线程如何访问MyList?

如果我使 MyList 成为 TThread 派生的 class 的成员,它位于线程的内存中并且线程可以直接访问它。 GetMyStruct() 如何访问 MyList

存储 MyList 并在不同线程中访问它的 best/prefered/common 方法是什么?

If I make MyList a global variable, it is located in the main thread's memory and GetMyStruct() can access it directly. How does the thread access MyList?

完全一样。进程中的所有线程都可以自由访问该进程内的全局变量。例如:

#include <vector>
#include <System.SyncObjs.hpp>

typedef struct
{
    char MyString[40 + 1];
    double MyDouble;
    bool MyBool;
} TMyStruct;

std::vector<TMyStruct> MyList;
TCriticalSection *Lock = NULL; // why not std::mutex instead?

class TMyThread : public TThread
{
    ...
};
TMyThread *Thread = NULL;

...

void __fastcall TMyThread::Execute()
{
    TMyStruct Data;
    ...
    Lock->Enter();
    try {
        MyList.push_back(Data);
    }
    __finally {
        Lock->Leave();
    }
    ...
}

...

void __declspec(dllexport) __stdcall StartThread ()
{
    Lock = new TCriticalSection;
    Thread = new TMyThread;
}

void __declspec(dllexport) __stdcall StopThread ()
{
    if (Thread) {
        Thread->Terminate();
        Thread->WaitFor();
        delete Thread;
        Thread = NULL;
    }
    if (Lock) {
        delete Lock;
        Lock = NULL;
    }
}

bool __declspec(dllexport) __stdcall GetMyStruct (int Index, TMyStruct* Data)
{
    if (!(Lock && Thread)) return false;

    Lock->Enter();
    try {
        *Data = MyList[Index];
    }
    __finally {
        Lock->Leave();
    }

    return true;
}

If I make MyList a member of the TThread-derived class, it is located in the thread's memory and the thread can access it directly. How does GetMyStruct() access MyList?

通过指向线程对象的指针访问它。例如:

#include <vector>
#include <System.SyncObjs.hpp>

typedef struct
{
    char MyString[40 + 1];
    double MyDouble;
    bool MyBool;
} TMyStruct;

class TMyThread : public TThread
{
protected:
    void __fastcall Execute();
public:
    __fastcall TMyThread();
    __fastcall ~TMyThread();

    std::vector<TMyStruct> MyList;
    TCriticalSection *Lock;
};

TMyThread *Thread = NULL;

...

__fastcall TMyThread::TMyThread()
    : TThread(false)
{
    Lock = new TCriticalSection;
}

__fastcall TMyThread::~TMyThread()
{
    delete Lock;
}

void __fastcall TMyThread::Execute()
{
    TMyStruct Data;
    ...
    Lock->Enter();
    try {
        MyList.push_back(Data);
    }
    __finally {
        Lock->Leave();
    }
    ...
}

void __declspec(dllexport) __stdcall StartThread ()
{
    Thread = new TMyThread;
}

void __declspec(dllexport) __stdcall StopThread ()
{
    if (Thread) {
        Thread->Terminate();
        Thread->WaitFor();
        delete Thread;
        Thread = NULL;
    }
}

bool __declspec(dllexport) __stdcall GetMyStruct (int Index, TMyStruct* Data)
{
    if (!Thread) return false;

    Thread->Lock->Enter();
    try {
        *Data = Thread->MyList[Index];
    }
    __finally {
        Thread->Lock->Leave();
    }

    return true;
}

What is the best/prefered/common way to store MyList and access it in a different thread?

这完全由您根据您的特定需求和项目设计来决定。