如何让LabView停止锁定我的.NET DLL
本文关键字:锁定 我的 NET DLL LabView | 更新日期: 2023-09-27 18:20:05
我正在试用LabView,尝试如何将其与.NET结合使用。我已经成功创建了一个小型应用程序,它可以读取仪表,在.NET中转换值,并在另一个仪表上显示结果。
问题是,当我试图添加到.NET项目并重建时,DLL被锁定,我无法覆盖它。NI声称LabView使用了卷影复制。但如果这是真的,我的DLL就不应该被锁定。
有没有办法让LabView停止锁定DLL?除了每次我想重建时都退出LabView之外,这似乎是一个乏味的修复。
我认为您的应用程序中发生的情况如下:
当Labview启动时,它会拉入应用程序的dll,将其紧紧锁定在内存中。因此,文件被锁定,Visual Studio将无法覆盖此文件(我在其他应用程序中直接看到过这种行为)。由于dll在Labview退出之前永远不会被释放,因此您需要找到一种方法来"释放"dll;技巧";每次重新编译时,Labview都会加载一个新的dll。
以下是我的建议:
在LabView中,不是像Chris Sterling建议的那样直接加载dll,而是要创建一个";包装器";dll,它将通过接口加载您的特定LabView dll
通过使用存储在包装器dll中的接口,您可以完全解耦这两个dll,这将防止包装器dll知道/锁定您的主dll。稍后,当您完成调试时,您可以直接将dll链接到LabView。
以下是代码的大致外观:
public class LabViewWrapper : IYourCustomClass
{
private IYourCustomClass _labViewClass;
private string labviewPath = "Full Path to labview dll";
public LabViewWrapper()
{
Assembly assembly;
try
{
using (FileStream fs = File.OpenRead(labviewPath))
{
using (MemoryStream ms = new MemoryStream())
{
byte[] buffer = new byte[1024];
int read = 0;
while ((read = fs.Read(buffer, 0, 1024)) > 0)
ms.Write(buffer, 0, read);
assembly = Assembly.Load(ms.ToArray());
ms.Close();
}
fs.Close();
}
Type t = assembly.GetType(IYourCustomClass);
_labViewClass= (IYourCustomClass)Activator.CreateInstance(t);
}
catch
{
// Unable to load dll dynamically
}
}
// Implement all the methods in your interface with something like the following:
/// <summary>
/// Your Custom Method
/// </summary>
public void CustomLabViewMethod()
{
_labViewClass.CustomLabViewMethod();
}
}
通过这种方式,您正在从内存加载dll,因此labview永远不会锁定您编译的原始dll。唯一真正的缺点是它确实使调试变得更加困难,如果你想插入断点,你可能需要直接引用源dll。
注:有一件事我不确定,但我相信会"计算";Labview是否足够聪明,可以在每次执行代码时重新构造对象,或者它是否只是在整个会话中保持相同的对象。如果它最终完成了稍后的操作,则需要向"添加代码;重新加载";每次启动自定义小部件时,文件系统中的dll。
您可以创建一个轻量级DLL包装器,它本身具有显式的主DLL运行时加载和卸载。这样包装器就会保持锁定状态,但您可以快速更新频繁更改的代码DLL。
我正在LV2012中用一个C#类做一个测试,该类在Labview VI的一个单独文件夹中有一个新的自定义类。我可以在VS2010中重新编译C#代码,而无需关闭Labview,但Labview看不到DLL的更改(如果有)。为了让Labview看到我的测试用例中的变化,它需要完全关闭并重新打开。
对于Labview C++DLL,您肯定必须关闭调用的VI,因为对DLL的引用是打开的。不过,您只需要关闭到"Labview启动"窗格。
您可以通过进入项目->属性->调试->启动外部程序,让VS在C#项目中自动生成Labview.exe。当您在VS中点击F5时,DLL会编译并生成Labview。然而,VS并没有自动将DLL附加到进程,这真的非常令人讨厌。不管有没有帮助,我都不知道。
就我个人而言,我喜欢C#方法与Labview集成的方式,但觉得C++更强大。使用C++时,您也可以以与上述类似的方式生成Labview,但它会自动将DLL附加到Labview.exe进程,使调试成为只需按F5即可完成的一步过程。你仍然可以在C++中使用类等,你只需要包装C函数就可以在Labview中调用它们。考虑到C++的一步调试和强大功能,我发现在Labview中使用外部代码时,它优于C#。
这里的术语有点不清楚,因为它指的是LV"调用"程序集,我不知道这是指在编辑时访问程序集还是在运行时实际调用它。如果是第二个,这可能解释了它被锁定的原因。
我不是.NET程序员,所以我不知道实际的解决方案是什么,但我猜你实际上不需要完全关闭LV来释放锁。关闭项目可能就足够了,尽管我知道这并不一定更好,如果锁定发生在流程级别,可能也无济于事。
gethttp://www.emptyloop.com/unlocker/unlocker -h
的命令行选项
在预生成中运行。在相关dll上使用unlock命令。
如果仅解锁没有帮助,请使用解锁+删除。
简单如
Unlocker mydllpath.dll /s /d
您会发现这种行为会根据dll的分布方式而变化。如果Labview通过磁盘上的静态位置(由路径输入指定)调用程序集,您会发现在Labview应用程序打开时无法重建dll。
然而,如果dll已注册,并且Labview按名称访问它,您可以随心所欲地重建和重新安装,一旦关闭并重新打开,Labview将更新其对dll的引用。
在通过COM Interop共享.Net程序集以及将其安装到GAC时,我无意中发现了这一点。
早在2017年,知识库就有关于这个主题的文章,但现在似乎不见了。
我在这里包含了关于加载程序集的官方Labview帮助指南。