Skip to content

Bug: GetString and GetRawBytes do not populate buffer when rc is successful #4

@MichaelPiran

Description

@MichaelPiran

I have problem regarding the functions "GetString()" and "GetRawBytes()" declared in goplctag.go file, they do not fill the buffer.

The problem is related to the function "copyPCharBytes()", i have tried to bypass that method and declaring the variable "cbuffer" as "cbuffer := (*C.char)(unsafe.Pointer(&buffer[0]))" and it worked for me.

Here is my code:

func main() {

	// ... //

	tag_path := fmt.Sprintf("protocol=ab_eip&gateway=%s&path=1,0&cpu=nx1p2&name=%s", ip_ipdentifier, TAG)

	tag := goplctag.Create(tag_path, DATA_TIMEOUT)
	if tag < 0 {
		fmt.Printf("ERROR %s: Could not create tag!\n", goplctag.DecodeError(int32(tag)))
		os.Exit(0)
	}

	if rc := goplctag.Status(tag); rc != goplctag.StatusOk {
		fmt.Printf("ERROR %s: Error setting up tag internal state.\n", goplctag.DecodeError(rc))
		goplctag.Destroy(tag)
		os.Exit(0)
	}

	// read the tag from plc
	if rc := goplctag.Read(tag, DATA_TIMEOUT); rc != goplctag.StatusOk {
		fmt.Printf("ERROR: Unable to read the data! Got error code %d: %s\n", rc, goplctag.DecodeError(rc))
		goplctag.Destroy(tag)
		os.Exit(0)
	}

	tagSize := goplctag.GetSize(tag)
	fmt.Printf("Tag size: %d bytes\n", tagSize)

	var offset int32 = 0
	strNum := 1
	for offset < tagSize {
		strCap := goplctag.GetStringLength(tag, offset) + 1 // +1 per il terminatore zero

		str := make([]byte, int(strCap))

		rc := goplctag.GetString(tag, offset, str, strCap)
		if rc != goplctag.StatusOk {
			goplctag.Destroy(tag)
			fmt.Printf("unable to get string %d, got error %s!", strNum, goplctag.DecodeError(rc))
			return
		}

		fmt.Fprintf(os.Stderr, "string %d (%d chars) = '%s'", strNum, len(str), string(str))

		strNum++
		offset += goplctag.GetStringTotalLength(tag, offset)
	}

	goplctag.Destroy(tag)
}

Below you see my successful workaround:

func GetString(tagId int32, stringStartOffset int32, buffer []byte, bufferLength int32) int32 {
	ctagId, ctagIdAllocMap := (C.int32_t)(tagId), cgoAllocsUnknown
	cstringStartOffset, cstringStartOffsetAllocMap := (C.int)(stringStartOffset), cgoAllocsUnknown

	cbuffer := (*C.char)(unsafe.Pointer(&buffer[0]))

	cbufferLength, cbufferLengthAllocMap := (C.int)(bufferLength), cgoAllocsUnknown
	__ret := C.plc_tag_get_string(ctagId, cstringStartOffset, cbuffer, cbufferLength)
	runtime.KeepAlive(cbufferLengthAllocMap)
	// runtime.KeepAlive(cbufferAllocMap)
	runtime.KeepAlive(cstringStartOffsetAllocMap)
	runtime.KeepAlive(ctagIdAllocMap)
	__v := (int32)(__ret)
	return __v
}

Is there a bug on the goplctag.go file or am I using it wrong?

example.txt

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions