I am trying to write a program that will allow me to read and write to a UDT. I started with the simple.c example and modified the commands to allow me to read and write to a UDT. Reading from the UDT works well, but I cannot write to the tag of my UDT type.
My path to the tag is:
#define TAG_PATH "protocol=ab-eip&gateway=192.168.3.68&path=1,0&cpu=LGX&name=DataBlock"
For test purposes, I created a UDT of 10 DINT.
The code to write to tag:
tag = plc_tag_create(TAG_PATH, DATA_TIMEOUT);
if (tag < 0) {
// NOLINTNEXTLINE
fprintf(stderr, "ERROR %s: Could not create tag!\n", plc_tag_decode_error(tag));
return 1;
}
iS7BufferOffset = 0;
iItem1 = 10;
memcpy(byPLCWriteData + iS7BufferOffset, &iItem1, sizeof(int));
iS7BufferOffset += sizeof(int);
iItem2 = 10;
memcpy(byPLCWriteData + iS7BufferOffset, &iItem2, sizeof(int));
iS7BufferOffset += sizeof(int);
iItem3 = 10;
memcpy(byPLCWriteData + iS7BufferOffset, &iItem3, sizeof(int));
iS7BufferOffset += sizeof(int);
iItem4 = 10;
memcpy(byPLCWriteData + iS7BufferOffset, &iItem4, sizeof(int));
iS7BufferOffset += sizeof(int);
iItem5 = 10;
memcpy(byPLCWriteData + iS7BufferOffset, &iItem5, sizeof(int));
iS7BufferOffset += sizeof(int);
iItem6 = 10;
memcpy(byPLCWriteData + iS7BufferOffset, &iItem6, sizeof(int));
iS7BufferOffset += sizeof(int);
iItem7 = 10;
memcpy(byPLCWriteData + iS7BufferOffset, &iItem7, sizeof(int));
iS7BufferOffset += sizeof(int);
iItem8 = 10;
memcpy(byPLCWriteData + iS7BufferOffset, &iItem8, sizeof(int));
iS7BufferOffset += sizeof(int);
iItem9 = 10;
memcpy(byPLCWriteData + iS7BufferOffset, &iItem9, sizeof(int));
iS7BufferOffset += sizeof(int);
iItem10 = 10;
memcpy(byPLCWriteData + iS7BufferOffset, &iItem10, sizeof(int));
iS7BufferOffset += sizeof(int);
rc = plc_tag_set_raw_bytes(tag, 0, byPLCWriteData, 40);
if(rc != PLCTAG_STATUS_OK) {
// NOLINTNEXTLINE
fprintf(stderr, "ERROR: Unable to write the data! Got error code %d: %s\n", rc, plc_tag_decode_error(rc));
plc_tag_destroy(tag);
return 1;
}
plc_tag_destroy(tag);
When I execute the code, the plc_tag_set_raw_bytes returns a 0, but the values in the PLC never change. I do not get any messages in the debug window until I exit the program. Then I get the following:
2026-08-16 13:20:28.077359 thread(2) tag(0) [AB_SESSION] INFO session_destroy:1148 Session sent 3 packets.
2026-08-16 13:20:28.077355 thread(4) tag(0) [AB_SESSION] INFO send_eip_request:2503 00032 00 00 00 00 b2 00 18 00 4e 02 20 06 24 01 0a 0e
2026-08-16 13:20:28.078448 thread(4) tag(0) [AB_SESSION] INFO send_eip_request:2503 00048 72 f9 3d f3 45 43 50 21 03 00 01 00 20 02 24 01
2026-08-16 13:20:28.078523 thread(4) tag(0) [PLATFORM] WARN socket_write:1937 socket write error rc=-1, errno=10054
2026-08-16 13:20:28.078548 thread(4) tag(0) [AB_SESSION] WARN send_eip_request:2530 Session is terminating.
2026-08-16 13:20:28.078612 thread(4) tag(0) [AB_SESSION] INFO send_forward_close_req:3067 Done
2026-08-16 13:20:28.078637 thread(4) tag(0) [AB_SESSION] WARN perform_forward_close:2668 Sending forward close failed, PLCTAG_ERR_ABORT!
2026-08-16 13:20:28.078668 thread(4) tag(0) [AB_SESSION] INFO perform_forward_close:2679 Done.
2026-08-16 13:20:28.078699 thread(4) tag(0) [AB_SESSION] WARN session_handler:1597 Forward close failed PLCTAG_ERR_ABORT!
I could not find any examples for reading/writing raw bytes.
I am using Visual Studio 2017 with the x86 dev library. I have tried both versions 2.7.1 and 2.6.16. The plc that I am communicating with is a CompactLogix 1769--L18ER-BB1B.
The simple.c software works, and the get_raw_bytes work, but the set_raw_bytes makes no change in the PLC.
One other thing was I had to destroy the tag, and create a new tag each time I read from the UDT.
Any help would be appreciated. Thanks.