Jump to content

How do I handle LabVIEW strings over COM to python


Recommended Posts

I want to call LabVIEW functions from a python script and trying to understand the memory handling of strings and arrays.

Let's say that I have a COM API created by LabVIEW with a function that look like this:

void Foo(LStrHandle *str)

I want to call this from python and use the library ctypes. I give below the code I have written so far:

from ctypes import*
mydll = cdll.LoadLibrary("MyDll.dll")

# A typedef for the signature of a LStrHandle
LVString = POINTER(POINTER(c_int))

# Cast a LStrHandle to a python string.
# LStrHandle is a int32 that tell the number of chars that following 
# direct after the int32 in memory.
def CastLVString(lvValue):
    if lvValue and lvValue.contents and lvValue.contents.contents:
    # Get the pointer from the pointer to pointer.
    lstr = lvValue.contents.contents
    # Get the value from the pointer that is the count.
    cnt = lstr.value
    if cnt > 0:
        # Get the bytes after cnt. Number of bytes is defined by cnt.
        str_bytes = cast(addressof(lstr) + sizeof(c_int32), POINTER(c_char * cnt))
        # Cast the bytes to a string.
        return str_bytes.contents.value.decode('utf-8')
    return ""

# Wrapper function for COM function Foo.
def Foo():
    mydll.Foo.argtypes = [ POINTER(LVString) ]

    str = LVString()

    mydll.Foo(byref(str))

    # Cast the LStrHandle to a python string and return.
    return CastLVString(message)

This works, but I wonder if it is correct. Aren't there better ways to handle strings (and vectors)? I wonder how the memory management works. I guess I have to tell LabVIEW that it can free the memory after I read the data. If so, how do I do it? I have seen that the function DSDisposePtr should be used if doing it from C, can this function be used in python?

 

 

By the way, the C signature for LStrHandler is as following:

/** @brief Long Pascal-style string types. */
typedef struct {
    int32   cnt;        /* number of bytes that follow */
    uChar   str[1];     /* cnt bytes */
} LStr, *LStrPtr, **LStrHandle;
Link to comment
  • 2 weeks later...

It looks fairly ok. But you have a problem. You need to free that handle and that is not trivial. You need to call DSDisposeHdl() from the LabVIEW manager functions, however it depends on various things as to what DLL that function needs to come from.

Most likely however does your DLL already export a helper function. Have you checked the header for your DLL? Isn’t there an additional function named DisposeLStr or similar exported? Calling that correctly will properly deallocate the handle after you are done with it.

One small correction, COM either means a serial communication port or the underlying technology for ActiveX (Component Object Model). There is a separate Python module to handle COM interfaces but that works differently. Here you simply call classic DLL functions.

Edited by Rolf Kalbermatter
Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.