【问题标题】:Share a variable between C and Labview?在 C 和 Labview 之间共享一个变量?
【发布时间】:2011-01-04 17:47:40
【问题描述】:

允许 C 代码定期访问从单独的 Labview 程序生成的整数的瞬时值的最佳方法是什么?

我有控制科学实验并每 20 毫秒记录一次数据的时间要求严格的 C 代码。我还有一些 labview 代码可以操作不同的仪器并每 100 毫秒输出一个整数值。我希望我的 C 代码能够记录来自 labview 的值。最好的方法是什么?

一个想法是让 Labview 循环将整数写入文件,并让 C 代码循环读取文件的值。 (如有必要,我可以在我的 C 代码中添加第二个线程。) Labview 还可以链接到 C dll。所以我也许可以用 C 语言编写一个 DLL,以某种方式促进两个程序之间的共享。这是可取的吗?我该怎么做?

【问题讨论】:

    标签: c variables labview


    【解决方案1】:

    我在这里有一个类似的应用程序,并使用带有 TCP_NO_DELAY 选项集的 TCP 套接字(禁用执行某种数据包缓冲的 Nagle 算法)。套接字应该允许 100 毫秒的更新速率没有问题,尽管实际的网络延迟将始终是一个未知变量。对于我的应用程序来说,只要它保持在某个限制以下就无关紧要(如果时间戳增量变得太大,还可以通过发送每个数据包的时间戳和红色大对话框来检查这一点:])。对你的申请有影响吗?即,每当 LV 仪器获取新样本时,它的值必须在 x 毫秒内到达 C 应用程序是否重要?

    您可能会使用 dll 方法,但它不像套接字那样简单,它会使两个应用程序更加相互依赖。不过,可变访问几乎是即时的。我至少看到了两种可能性:

    • 将您的整个 C 应用程序放入 dll 中(起初可能看起来很奇怪,但它确实有效),并让 LV 加载它并在其上调用方法。例如,启动您的应用程序 LV 调用 dll 的 Start() 方法,然后在循环中 LV 获取它的样本,它调用 dll 的 NewSampleValue(0 方法左右。这也意味着您的应用程序无法独立运行,除非您为其编写单独的主机进程。
    • 查看共享进程内存,让 C 应用程序和另一个 dll 共享公共内存。 LV 将加载该 dll 并在其上调用一个方法以将一个值写入共享内存,然后 C 应用程序可以在轮询一个标志后读取它(这需要一个锁!)。
    • 也可以让 C 应用程序使用 dll/activeX/? 调用 LV 程序?电话,但我不知道该系统是如何工作的..

    我肯定会远离文件方法:磁盘 I/O 可能是一个真正的瓶颈,而且它还有锁定问题,这对于解决文件来说很麻烦。当 LV 正在写入文件时,C 应用程序无法读取文件,反之亦然,这可能会导致额外的延迟。

    在旁注中,您可以看到上述每种方法都使用推送或拉取模型(TCP 可以以两种方式实现),这可能会影响您最终决定采用哪种方式。. Push = LV 直接向 C 应用发出信号,pull = C 应用必须轮询标志或向 LV 询问值。

    【讨论】:

      【解决方案2】:

      我是 National Instruments 的一名员工,我想确保您不会错过 LabWindows/CVI(National Instruments C 开发环境)提供的网络变量 API。 Network Variable API 将允许您通过共享变量轻松与 LabVIEW 程序进行通信 (http://zone.ni.com/devzone/cda/tut/p/id/4679)。在阅读这些链接时,请注意网络变量和共享变量是同一个东西 - 不同的名称是不幸的......

      网络变量 API 的好处在于它允许与 LabVIEW 轻松互操作,它提供了强类型通信机制,并且它提供了一个回调模型,用于在网络/共享变量的属性(例如值)发生更改时进行通知。

      您可以通过安装 LabWindows/CVI 获得该 API,但不必使用 LabWindows/CVI 环境。头文件位于 C:\Program Files\National Instruments\CVI2010\include\cvinetv.h,.lib 文件位于 C:\Program Files\National Instruments\CVI2010 \extlib\msvc\cvinetv.lib 可以与您使用的任何 C 开发工具链接。

      【讨论】:

      • 谢谢。看起来很有前途。你知道我是否可以重新分发 .h 文件和 .lib 文件吗?这是一个科学项目,到目前为止,一切都是开源的。
      • 共享变量...名气不大。或者,正如one user put it,他们“在每个发布周期都无法预测地获得/失去错误”。这并不意味着它们不应该被使用,只是要小心。
      • 很遗憾,许可协议不允许重新分发开发库。附带说明一下,您必须将 CVI 运行时与您的应用程序一起分发才能使用网络/共享变量。
      【解决方案3】:

      我跟进了@stijn 的一个理想:

      让 C 应用程序和另一个 dll 共享公共内存。 LV 将加载该 dll 并在其上调用一个方法以将值写入共享内存,然后 C 应用程序可以在轮询标志后读取它(这需要锁定!)。

      我编写了 InterProcess 库,可在此处获得:http://github.com/samuellab/InterProcess

      InterProcess 是一个紧凑的通用库,它使用CreateFileMapping()MapViewOfFile() 设置Windows 共享内存。它允许用户在任意数量的命名字段中无缝地存储任何类型的值(int、char、你的 struct.. 等等)。它还实现了 Mutex 对象以避免冲突和竞争条件,并将所有这些抽象到一个干净简单的接口中。在 Windows XP 上测试。应该适用于任何现代 Windows。

      为了连接我现有的 C 代码和 labview,我编写了一个小型包装 DLL,它位于 InterProcess 之上,只公开我的 C 代码或 labview 需要访问的特定函数。这样,所有的共享内存就被完全抽象掉了。

      希望其他人会发现此代码有用。

      【讨论】:

      • 刚刚看到这个,看起来很有趣。当我必须开始一个新项目时,我会看看它..
      • 如果有机会,请务必查看。毕竟这是你的主意。
      猜你喜欢
      • 2012-10-27
      • 2013-07-26
      • 2018-04-25
      • 2011-09-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-14
      相关资源
      最近更新 更多