suffer 发表于 2006-10-20 15:56

Call Library Node 函数返回的字符串为什么不用在 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编出来的函数,根本不需要内存分配回收的问题。有了内存分配就是烦啊。

转自http://ruanqizhen.spaces.live.com/Blog/cns!1pU-rgQVTuuWM1TX8W8PfmDA!1073.entry
版权归原作者所有

younghorse 发表于 2006-10-23 12:55

哇靠靠~~~~~~~~ 老大果然是强啊,支持!!!!!!!

realhappy 发表于 2006-10-23 13:13

原帖由 suffer 于 2006-10-20 15:56 发表
Call Library Node 是 LabVIEW 中调用 DLL 函数的节点。如果被调用的函数有一参数数据类型为 char*,用来输出字符串。我们需要在 CLN 中这个参数对应的左侧接线端连进一个字符串,并且输入字符串的长度要保证大于 ...
确实是高人,没有这么深究过。
页: [1]
查看完整版本: Call Library Node 函数返回的字符串为什么不用在 VI 中先分配内存