Qizhen's profileLabVIEWPhotosBlogListsMore Tools Help

Blog


    调用动态链接库 5 - 作为函数返回值的字符串为什么不用在 VI 中先分配内存

        Call Library Node 是 LabVIEW 中调用 DLL 函数的节点。如果被调用的函数有一参数数据类型为 char*,用来输出字符串。我们需要在 CLN 中这个参数对应的左侧接线端连进一个字符串,并且输入字符串的长度要保证大于输出字符串的长度。这个输入字符串的内容是没有用的,它只被用作是被开辟的内存,保存输出字符串。否则,会出现数组越界的运行错误,LabVIEW会莫名其妙死掉。
        更糟糕的是,LabVIEW 不会在刚好出现数组越界错误时死掉,而是在之后的某一部确定时候死掉。如果你意识不到自己的程序中有这种错误,或者你有几百个类似的 CLN,那你调试起来可能会类似的。
     
        有人问我,如果函数不是用参数输出字符串而是返回字符串,CLN 返回参数是没有左接线端的。这可咋开辟内存捏?
        我打开 LabVIEW 一试,可不是嘛。函数返回字符串的地方根本没法输入任何信息。自己编了一个DLL试了试,发现 CLN 是可以正确输出函数返回的字符串的,不需要特别指定字符串的大小。
        今天早上起得太早,于是就有点发晕,心想,如果既然 LabVIEW 不需要为函数返回的字符串开辟内存,干嘛非要难为我们为参数输出的字符串开辟内存。否则可以避免多少潜在的错误啊。DLL 函数参数输出字符串是个比较常见的导致程序崩溃的陷阱。
     
        琢磨了半天,脑袋才清醒过来。所谓返回或输出字符串是口头上的语言。换成计算机的语言来解释就清楚了:)
        函数返回字符串的情况,实际上是函数返回了一个指向字符串指针。既然是函数返回的,LabVIEW就可以得到该指针,进而就可以得到它所指的字符串。在LabVIEW内部,调用以下 strlen() 得到字符串的长度,开辟一个相应大小的buffer,再调用以下 strcpy() 就把这个字符串考到 LabVIEW 控件的数据区了。
        而参数输出字符串的情况并不是真的输出,而是函数要求输入一个指针。LabVIEW 必须为DLL函数提供这样一个指针。而LabVIEW自己又不能自动开辟一片缓存就把指针传给函数,因为这时候我们想要的字符串还不存在呢,LabVIEW没办法知道应该开辟多大的缓存。只好把指定缓存大小的任务交给编程人员了:(
     
        LabVIEW 编程如果不是考虑调用C编出来的函数,根本不需要内存分配回收的问题。有了内存分配就是烦啊。
     
    我和 LabVIEW》目录

    Comments (3)

    Please wait...
    Sorry, the comment you entered is too long. Please shorten it.
    You didn't enter anything. Please try again.
    Sorry, we can't add your comment right now. Please try again later.
    To add a comment, you need permission from your parent. Ask for permission
    Your parent has turned off comments.
    Sorry, we can't delete your comment right now. Please try again later.
    You've exceeded the maximum number of comments that can be left in one day. Please try again in 24 hours.
    Your account has had the ability to leave comments disabled because our systems indicate that you may be spamming other users. If you believe that your account has been disabled in error please contact Windows Live support.
    Complete the security check below to finish leaving your comment.
    The characters you type in the security check must match the characters in the picture or audio.

    To add a comment, sign in with your Windows Live ID (if you use Hotmail, Messenger, or Xbox LIVE, you have a Windows Live ID). Sign in


    Don't have a Windows Live ID? Sign up

    Qizhen Ruanwrote:
    动态库与LabVIEW之间的数据传递实际上都是复制的。所以一旦数据被传递到LabVIEW中,即便动态库中的数据是局部变量,被销毁,也不会影响到LabVIEW中的数据。
    May 23
    Kunwrote:
    如果在动态链接库里面不分配内存的话,怎么能够返回字符串?函数执行完以后,数据由于不是全局的,数据所在内存会被收回的。
    May 22
    Weiwrote:
    如果是自己写这个DLL,那就还有一种解决的办法:用LabVIEW的C导出库,用String的Handle传递Char*,在DLL里用的时候,LabVIEW会给这个字符串自动分配内存的,这个问题就不复存在了。
    July 22

    Trackbacks

    The trackback URL for this entry is:
    http://ruanqizhen.spaces.live.com/blog/cns!5852D4F797C53FB6!1128.trak
    Weblogs that reference this entry
    • None