在mono下导入DLL并运行应用程序

时间:2012-11-01 16:13:29

标签: .net dll import mono delphi-prism

我导入" winmm.dll"使用以下代码。

  MyUtils = public static class
  private
  protected
  public
    [DllImport("winmm.dll")]
    class method timeBeginPeriod(period:Integer):Integer; external;
    [DllImport("winmm.dll")]
    class method timeEndPeriod(period:Integer):Integer; external;
  end;

按如下方式访问方法。

MyUtils.timeBeginPeriod(1); //within winform load event
MyUtils.timeEndPeriod(1);   //within winform formclosing event

在Windows 7下,它可以正常运行。在Linux系统上的mono下,它也有效,但有一个例外。程序启动后,会弹出一个消息框,其中包含导入的dll名称和OK按钮,如下所示。当我单击“确定”按钮时,我的程序将继续并按预期运行而不会出现任何错误。

enter image description here

我已经梳理了我的程序,看看我是否故意在任何地方显示dll文件名,但我根本无法找到类似的内容。

编辑:更多信息,我需要使用winmm.dll的原因是我需要能够将线程睡眠粒度或默认延迟调整到大约1毫秒或接近它 - 不播放电影或音乐文件。我能够调整的唯一方法是通过这些方法timeBeginPeriodtimeEndPeriod。这样我的程序就能通过串口成功通话。我的计划是每隔24/7/365天不间断地每隔几毫秒来回交谈。沟通达到90%或更高是至关重要的。在导入dll文件后,我的程序通信在Windows和Linux上完美无缺,除了我在单声道Linux上获取那个烦人的消息框。

我以前从未见过或听说过这样的问题。有谁为什么?

谢谢,

1 个答案:

答案 0 :(得分:4)

我认为对Mono如何运作存在一些误解。 WinMM.dll是Windows的本机二进制文件。 Mono不会自动允许您导入winmm.dll并在Linux环境中使用它。我猜你的程序没有运行,因为timeBeginPeriodtimeEndPeriod不会执行。

除非你有一些适用于Linux的Windows多媒体模块的端口,否则这不起作用。 Mono移植到System.Media.SoundPlayer有什么方法可以从中获得所需的一切吗?

Mono中的P / Invoke工作得很好,但是你仍然需要为每个平台构建原生的二进制文件。

有一篇关于Porting to linux - replacement for winmm

的文章

您可能需要查看LGPL LAME

<强>更新

问题在于,无论分辨率如何,Thread.sleep都不能准确地创建确定性行为。您不能使用Thread.sleep来同步具有接近1ms粒度的内容。 JVM和.NET平台都可以接近1ms的精度,但是,这不能保证。如果系统繁忙,您可能无法及时将上下文切换回到您的线程,这意味着它可能是3ms,或10ms,甚至更糟。

您应该搜索两件事。 Linux上的高分辨率计时器。以及如何创建实时系统。由于您需要几乎每天进行通信,因此您需要研究实时系统并找出如何为计时创建确定性系统。

大多数计时器只能让你接近30毫秒的分辨率。

如果你在Linux上找到一个高分辨率计时器,你仍然需要考虑上下文切换和时间流逝来弥补丢失的时间,或者甚至在亚毫秒处理中减慢。

我意识到你声称它在Windows上运行良好,但我试图解释它并不像你想象的那样工作。它现在可以工作,但是有很多场景可以在该机器上运行,这会导致系统不以1ms的间隔处理数据,因此需要您在以后调试系统。

支持我的一些事情:How to make thread sleep less than a millisecond on Windows