Hi Microsoft team, I need to write a Dynamic array for Data that's coming in on the serial port from an Arduino microcontroller, any advice on How I could do this with this code, I need to send that data for further processing. This code just logs data to the terminal, but I need to send it off for further processing by another application, I was thinking of storing the data in a dynamic array that will increase in size as the data comes in is this even a good idea and is it possible to do this with the Threadpool API
#include <windows.h>
#include <stdio.h>
// Context struct to pass to threadpool callback
typedef struct {
HANDLE hCom; // Serial port handle
PTP_IO pIo; // Threadpool I/O object
BYTE buffer[256]; // Buffer for serial data
DWORD dwRead; // Bytes read
OVERLAPPED overlapped; // Overlapped structure
BOOL waitingOnRead; // Flag for read state
} SerialContext;
// Threadpool I/O completion callback
VOID CALLBACK SerialIoCallback(
PTP_CALLBACK_INSTANCE Instance,
PVOID Context,
PVOID Overlapped,
ULONG IoResult,
ULONG_PTR NumberOfBytesTransferred,
PTP_IO Io
) {
UNREFERENCED_PARAMETER(Instance);
SerialContext* ctx = (SerialContext*)Context;
if (IoResult != NO_ERROR) {
printf("I/O error: %lu (Bytes: %lu)\n", IoResult, NumberOfBytesTransferred);
return;
}
if (NumberOfBytesTransferred > 0) {
ctx->buffer[NumberOfBytesTransferred] = '\0'; // Null-terminate
printf("Received: %s", ctx->buffer); // Print ASCII data
}
// Restart async read
ZeroMemory(&ctx->overlapped, sizeof(OVERLAPPED));
ctx->overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (ctx->overlapped.hEvent == NULL) {
printf("CreateEvent failed: %lu\n", GetLastError());
return;
}
StartThreadpoolIo(ctx->pIo);
if (!ReadFile(ctx->hCom, ctx->buffer, sizeof(ctx->buffer) - 1, NULL, &ctx->overlapped)) {
if (GetLastError() != ERROR_IO_PENDING) {
printf("ReadFile failed: %lu\n", GetLastError());
CancelThreadpoolIo(ctx->pIo);
CloseHandle(ctx->overlapped.hEvent);
}
}
}
int main() {
// Initialize context
SerialContext ctx = { 0 };
ctx.waitingOnRead = FALSE;
// Open serial port
ctx.hCom = CreateFile(
L"\\\\.\\COM7", // Adjust COM port as needed
GENERIC_READ,
0,
NULL,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
NULL
);
if (ctx.hCom == INVALID_HANDLE_VALUE) {
printf("CreateFile failed: %lu\n", GetLastError());
return 1;
}
// Configure DCB
DCB dcb = { 0 };
dcb.DCBlength = sizeof(dcb);
if (!GetCommState(ctx.hCom, &dcb)) {
printf("GetCommState failed: %lu\n", GetLastError());
CloseHandle(ctx.hCom);
return 1;
}
dcb.BaudRate = CBR_9600;
dcb.ByteSize = 8;
dcb.Parity = NOPARITY;
dcb.StopBits = ONESTOPBIT;
dcb.fDtrControl = DTR_CONTROL_ENABLE;
if (!SetCommState(ctx.hCom, &dcb)) {
printf("SetCommState failed: %lu\n", GetLastError());
CloseHandle(ctx.hCom);
return 1;
}
// Set timeouts
COMMTIMEOUTS timeouts = { 0 };
timeouts.ReadIntervalTimeout = 50;
timeouts.ReadTotalTimeoutConstant = 50;
timeouts.ReadTotalTimeoutMultiplier = 10;
if (!SetCommTimeouts(ctx.hCom, &timeouts)) {
printf("SetCommTimeouts failed: %lu\n", GetLastError());
CloseHandle(ctx.hCom);
return 1;
}
// Purge stale data
if (!PurgeComm(ctx.hCom, PURGE_RXCLEAR | PURGE_RXABORT)) {
printf("PurgeComm failed: %lu\n", GetLastError());
CloseHandle(ctx.hCom);
return 1;
}
// Create threadpool I/O
ctx.pIo = CreateThreadpoolIo(ctx.hCom, SerialIoCallback, &ctx, NULL);
if (ctx.pIo == NULL) {
printf("CreateThreadpoolIo failed: %lu\n", GetLastError());
CloseHandle(ctx.hCom);
return 1;
}
// Initialize OVERLAPPED
ZeroMemory(&ctx.overlapped, sizeof(OVERLAPPED));
ctx.overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (ctx.overlapped.hEvent == NULL) {
printf("CreateEvent failed: %lu\n", GetLastError());
CloseThreadpoolIo(ctx.pIo);
CloseHandle(ctx.hCom);
return 1;
}
// Start first read
StartThreadpoolIo(ctx.pIo);
if (!ReadFile(ctx.hCom, ctx.buffer, sizeof(ctx.buffer) - 1, NULL, &ctx.overlapped)) {
if (GetLastError() != ERROR_IO_PENDING) {
printf("ReadFile failed: %lu\n", GetLastError());
CancelThreadpoolIo(ctx.pIo);
CloseHandle(ctx.overlapped.hEvent);
CloseThreadpoolIo(ctx.pIo);
CloseHandle(ctx.hCom);
return 1;
}
}
printf("Serial reader started. Press Ctrl+C to exit.\n");
// Main loop to keep program alive
while (1) {
Sleep(1000); // Keep main thread alive; callbacks handle I/O
}
// Cleanup (unreachable due to loop, but for completeness)
CancelThreadpoolIo(ctx.pIo);
WaitForThreadpoolIoCallbacks(ctx.pIo, FALSE);
CloseThreadpoolIo(ctx.pIo);
CloseHandle(ctx.overlapped.hEvent);
CloseHandle(ctx.hCom);
return 0;
}