在 C 和 Labview 之间共享变量?

发布于 2024-10-10 18:50:50 字数 328 浏览 0 评论 0原文

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

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

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

What is the best way to permit C code to regularly access the instantaneous value of an integer generated from a separate Labview program?

I have time-critical C code that controls a scientific experiment and records data once every 20ms. I also have some labview code that operates a different instrument and outputs an integer value ever 100ms. I want my C code to be able to record the value from labview. What is the best way to do this?

One idea is to have Labview write the integer to file in a loop, and have the C code read the value of the file in a loop. (I could add a second thread to my C code if necessary.) Labview can also link to C dll's. So I might be able to write a DLL in C that somehow facilitates sharing between the two programs. Is that advisable? How would I do that?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

那片花海 2024-10-17 18:50:50

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

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

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

我肯定会远离文件方法:磁盘I/O 可能是一个真正的瓶颈,而且它还存在锁定问题,在 LV 写入文件时,C 应用程序无法读取该文件,反之亦然,这可能会带来额外的延迟

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

I have a similar application here and use TCP sockets with the TCP_NO_DELAY option set (disables the Nagle algorythm which does some sort of packet buffering). Sockets should allow for a 100mSec update rate without problems, although the actual network delay will always remain an unknown variable. For my application this does not matter as long as it stays under a certain limit (this is also checked for by sending a timestamp with each packet and big red dialog boxes if timestamp delta becomes too large :]). Does it matter for your application? Ie, is it important that whenever the LV instrument acquires a new sample it's value has to make it to the C app within x mSec?

You might get the dll approach working, but it's not as straightforward as sockets and it will make the two applications more dependant of each other. Variable acces will be pretty much instantaneous though. I see at least two possibilities:

  • put your entire C app in a dll (might seem a weird approach at first but it works), and have LV load it and call methods on it. Eg to start your app LV calls dll's Start() method, then in the loop LV acquires it's samples it calls the dll's NewSampleValue(0 method or so. Also means your app cannot run standalone unless you write a seperate host process for it.
  • look into shared process memory, and have the C app and another dll share common memory. LV will load that dll and call a method on it to write a value to the shared memory, then the C app can read it after polling a flag (which needs a lock!).
  • it might also be possible to have the C app call the LV program using dll/activeX/? calls but I don't know how that system works..

I would definitely stay away from the file approach: disk I/O can be a real bottleneck and it also has the locking problem which is messy to solve with files. C app cannot read the file while LV is writing it and vice-versa which might introduce extra delays.

On a sidenote, you can see that each of the approaches above either use a push or pull model (the TCP one can be implemented in both ways), this might affect your final decision of which way to go.. Push = LV signals the C app directly, pull = C app has to poll a flag or ask LV for the value.

冷弦 2024-10-17 18:50:50

我是 National Instruments 的一名员工,我想确保您没有错过 LabWindows/CVI(National Instruments C 开发环境)提供的网络变量 API。 网络变量 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 开发工具链接。

I'm an employee at National Instruments and I wanted to make sure you didn't miss the Network Variable API that is provided with LabWindows/CVI, the National Instruments C development environment. The the Network Variable API will allow you to easily communicate with the LabVIEW program over Shared Variables (http://zone.ni.com/devzone/cda/tut/p/id/4679). While reading these links, note that a Network Variable and a Shared Variable are the same thing - the different names are unfortunate...

The nice thing about the Network Variable API is that it allows easy interoperability with LabVIEW, it provides a strongly typed communication mechanism, and it provides a callback model for notification when the Network/Shared variable's properties (such as value) change.

You can obtain this API by installing LabWindows/CVI, but it is not necessary to use the LabWindows/CVI environment. The header file is available at C:\Program Files\National Instruments\CVI2010\include\cvinetv.h, and the .lib file located at C:\Program Files\National Instruments\CVI2010\extlib\msvc\cvinetv.lib can be linked in with whatever C development tools you are using.

撩动你心 2024-10-17 18:50:50

我遵循了 @stijn 的一个理想:

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

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

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

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

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

I followed up on one of @stijn's ideals:

have the C app and another dll share common memory. LV will load that dll and call a method on it to write a value to the shared memory, then the C app can read it after polling a flag (which needs a lock!).

I wrote the InterProcess library, available here: http://github.com/samuellab/InterProcess

InterProcess is a compact general library that sets up windows shared memory using CreateFileMapping() and MapViewOfFile(). It allows the user to seamlessly store values of any type (int, char, your struct.. whatever) in an arbitrary number of named fields. It also implements Mutex objects to avoid collisions and race conditions, and it abstracts away all of this in a clean and simple interface. Tested on Windows XP. Should work with any modern Windows.

For interfacing between my existing C code and labview, I wrote a small wrapper DLL that sits on top of InterProcess and exposes only the specific functions that my C code or labview need to access. In this way, all of the shared memory is completely abstracted away.

Hopefully someone else will find this code useful.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文