【问题标题】:Handling an exception thrown from inside a dll处理从 dll 内部抛出的异常
【发布时间】:2014-09-10 07:44:07
【问题描述】:

我正在为一个加载 dll 的学校项目工作。

加载的 dll 是我的程序和 Twincat 系统管理器之间的桥梁,它通过本地网络形成计算机和 PLC 之间的桥梁。

我需要通过从 plc 到我的程序的整个链来读取变量。

这就是我这样做的方式:

Public Function adsReadReal(ByVal Variabelenaam As String) As Single
    Dim ds = New TwinCAT.Ads.AdsStream(4 * 8) ' new data stream
    Dim br = New System.IO.BinaryReader(ds) 'new binary
    Dim hVar = New Integer
    Try
        ConState(1) 
        tcclient = New TcAdsClient
        ConState(2)
        tcclient.Connect(Form1.amsAdress, 801) 'connects the tcclient to the PLC
        hVar = tcclient.CreateVariableHandle(Variabelenaam) 'creats a handle for the variable
        tcclient.Read(hVar, ds) 'read it
        ConState(5)
        Return br.ReadSingle() 'convert it from binary to readable for vb
    Catch ex As Exception
        ConState(0)
        PrintEx(ex) 'print out the exception
    finally
        tcclient.Dispose() 'make the object stop being used to prevent a lingering connection
    End Try
    Return False
End Function

现在程序在连接模块的开始处加载一个名为TwinCAT.ADS.dll 的dll。如果 Twincat 系统管理器正在运行程序正常结束,但当它不是时它崩溃并给我这个错误:

System.DllNotFoundException 未处理
Message="Kan DLL tcadsdll.dll niet laden: Kan opgegeven module niet vinden. (Uitzondering van HRESULT: 0x8007007E)"
Source="TwinCAT.Ads"
类型名称=""
堆栈跟踪:
bij TwinCAT.Ads.Internal.TcAdsDllWrapper.TcAdsDll.AdsAmsUnRegisterRouterNotification()
bij TwinCAT.Ads.Internal.TcAdsDllWrapper.AmsUnRegisterRouterNotification(布尔 throwAdsException)
bij TwinCAT.Ads.Internal.TcLocalSystem.Dispose(布尔处理)
bij TwinCAT.Ads.Internal.TcLocalSystem.Finalize()

大致翻译为:

无法加载 DLL tcadsdll.dll:找不到给定的模块。 (例外于 HRESULT: 0x8007007E)

这不是我导入的dll,所以一定是来自TwinCAT.ADS.dll

如何防止程序向我抛出此错误,而是和平关闭程序?我试图捕获所有可能的 dll 相关操作的异常。

来源也在 Bitbucket 上。我会应要求将其公开。

Beckhoff 官方网站上的一些链接,但很不方便:

http://infosys.beckhoff.com/espanol.php?content=../content/1034/tcquickstart/html/tcquickstart_samplevisualbasicnet.htm&id=10449

编辑: 显然使用 tcclient.dispose() 会导致错误,因为使用了 finnaly 语句而不是在 try 块之后使用

编辑:这当前捕获了异常但它不处理它。

Dim currentDomain As AppDomain = AppDomain.CurrentDomain
AddHandler currentDomain.UnhandledException, AddressOf MyHandler
Dim tick As Byte = 0

Sub MyHandler(sender As Object, args As UnhandledExceptionEventArgs)
   Dim ex As Exception = DirectCast(args.ExceptionObject, Exception)
   MsgBox("exception tick" & Str(tick))
   tick = tick + 1
   PrintEx(ex)
End Sub

编辑: 异常没有被正确捕获,因为在 vs2008 中发生了几个错误,但是在我按 F5(继续)后出现了勾号

程序直接运行时,我只看到1个Tick。然后windows报错。

【问题讨论】:

  • 只是一个旁注,在你的 catch 语句之后添加一个 finally 子句。这样可以确保即使程序异常关闭也会进行处理。
  • 在我看来,您缺少导入的库的依赖项。
  • @dwerner 在 Twincat 正常运行时不会发生。
  • 程序集可以在运行时加载。我不知道你会如何阻止不是你自己的代码尝试加载它。
  • @dwerner 是否可以在没有提升的情况下查看正在运行的进程?如果是这样,我可以阻止程序启动任何需要 dll 的对象并将其全部关闭。

标签: vb.net visual-studio-2008 error-handling ads


【解决方案1】:

您是否尝试过未处理的异常处理程序?

Dim currentDomain As AppDomain = AppDomain.CurrentDomain
AddHandler currentDomain.UnhandledException, AddressOf MyHandler

Sub MyHandler(sender As Object, args As UnhandledExceptionEventArgs)
   Dim e As Exception = DirectCast(args.ExceptionObject, Exception)
   Console.WriteLine("MyHandler caught : " + e.Message)
End Sub

【讨论】:

  • AddHandler 在此处无法识别。给出:“语法错误。”
  • 确保你把它放在正确的地方:msdn.microsoft.com/en-us/library/…
  • 您的错误必须来自您定义此处理程序的位置以外的其他地方,否则将被处理。
  • 好的,我在一些修复后发现了异常。但是我该如何解决呢?
  • 显然您调用的 DLL 正在寻找另一个文件。因此,“解决”您的问题的唯一方法是联系 DLL 的开发人员。但如果我的回答有帮助,请接受:)
猜你喜欢
  • 1970-01-01
  • 2016-01-06
  • 1970-01-01
  • 2013-07-24
  • 1970-01-01
  • 2011-05-07
  • 1970-01-01
  • 1970-01-01
  • 2018-08-31
相关资源
最近更新 更多