我正在尝试LabView,试验如何将它与.NET结合使用。我设法创建了一个小应用程序,它读取一个仪表,转换.NET中的值,并在另一个仪表上显示结果。
问题是,当我尝试添加到.NET项目并重建时,DLL被锁定,我无法覆盖它。 NI claims that LabView uses Shadow Copying。但如果这是真的,我的DLL就不应该被锁定。
有什么方法可以让LabView停止锁定DLL?除了每次我想重建时都退出LabView,这似乎是一个乏味的修复。
答案 0 :(得分:5)
当Labview启动时,它会拉入应用程序的dll,将其紧紧锁定在内存中。因此,文件被锁定,Visual Studio将无法覆盖此文件(我已在其他应用程序中直接看到此行为)。由于dll在Labview退出之前永远不会被释放,因此每次重新编译时都需要找到一种“欺骗”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。
答案 1 :(得分:4)
您可以创建一个轻量级DLL包装器,它本身具有显式运行时加载和卸载主DLL。这样包装器保持锁定状态,但您可以快速更新频繁更改的代码DLL。
答案 2 :(得分:2)
我正在LV2012中使用C#类进行测试,其中一个新的自定义类位于Labview VI的单独文件夹中。我能够在VS2010中重新编译C#代码而无需关闭Labview,但Labview没有看到DLL的更改(如果有的话)。要让Labview查看我的测试用例中的更改,需要将其完全关闭并重新打开。
对于Labview C ++ DLL,您肯定必须关闭调用的VI,因为对DLL的引用保持打开状态。您只需要关闭Labview Start-up窗格即可。
您可以让VS自动在C#项目中生成Labview.exe,方法是转到Project-&gt; Properties-&gt; Debug-&gt;启动外部程序。当您在VS中点击F5时,DLL会编译并生成Labview。但是,VS不会自动将DLL附加到进程,这实际上是非常令人讨厌的。 Dunno,如果这有帮助或没有。
就个人而言,我喜欢C#方法与Labview集成的方式,但发现C ++更强大。使用C ++,你也可以用与上面类似的方式生成Labview,但它会自动将DLL附加到Labview.exe进程,使调试成为一个只需点击F5的过程。你仍然可以在C ++中使用类等,你只需要包装C函数在Labview中调用它们。鉴于C ++的一步调试和强大功能,我发现它在Labview中使用外部代码时优于C#。
答案 3 :(得分:1)
术语有点不清楚,因为它在谈论LV“调用”程序集,我不知道这是指在编辑时访问程序集还是在运行时实际调用它。如果是第二个,这可能解释了为什么它被锁定了。
我不是.NET程序员,所以我不知道实际的解决方案是什么,但我猜你实际上并不需要完全关闭LV以释放锁。关闭项目是可能的,虽然我知道这不一定更好,如果锁在进程级别发生,它可能无济于事。
答案 4 :(得分:1)
获取http://www.emptyloop.com/unlocker/
unlocker -h
用于其命令行选项
在预建中运行。在相关的dll上使用unlock命令。
如果只解锁无法使用解锁+删除。
简单如
Unlocker mydllpath.dll /s /d
答案 5 :(得分:1)
您会发现此行为随dll的分发方式而改变。 如果Labview通过磁盘上的静态位置(由路径输入指定)调用程序集,则会发现在Labview应用程序打开时无法重建dll。
但是,如果dll被注册并且Labview通过名称访问它,您可以重建并重新安装您的内心内容,一旦关闭并重新打开DLL,Labview就会更新其对DLL的引用。
当我通过COM Interop共享.Net程序集并将其安装到GAC时,偶然发现了这一点。
最近在2017年就曾有关于该主题的知识库文章,但现在似乎已丢失。
我已包含有关加载程序集here的Labview官方帮助指南。