DOBON.NETプログラミング道掲示板
(現在 過去ログ1 を表示中)

[ 最新記事及び返信フォームをトピックトップへ ]

■33206 / inTopicNo.1)  Lawicel社 CANUSB コールバック関数に関して
  
□投稿者/ あらいぐま 一般人(1回)-(2016/01/05(Tue) 14:15:21)
  • アイコン環境/言語:[Windows7 32bit VB.net(VS2012) .NET Framework 4] 
    分類:[.NET] 

    いつも役に立つ情報をいただきありがとうございます。
    今回、標記コールバック関数の使い方でつまずいてしまい投稿させていただきました。
    皆様からアドバイスいただけましたら幸いです。

    環境:Windows7(32bit) VS2012(VB2012) 
    Lawicel社dll(canusbdrv.dll)を使用

    やりたいこと:コールバック関数を使用してデータ受信時に受信データを表示させたい

    (1)現在下記の内容でデータ受信時にReciveCallBackが呼び出されていることは確認できました。

    Private Sub Open_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles Open.Click
    '■■■CANポート オープン処理■■■
    Dim nRet As Integer

    '///指定されたデバイス(シリアル番号を指定)をオープンする
    h = Lawicel.CANUSB.canusb_Open("LWZ55LBC", "500", Lawicel.CANUSB.CANUSB_ACCEPTANCE_CODE_ALL, Lawicel.CANUSB.CANUSB_ACCEPTANCE_MASK_ALL, 0)

    '///正常にポートがオープンできたらコールバックを設定
    If (h <> 0) Then
    nRet = Lawicel.CANUSB.canusb_setReceiveCallBack(h, AddressOf Me.ReciveCallBack)
    End If

    End Sub

    Private Sub ReciveCallBack()
    '■■■CANデータ受信時■■■
    Console.WriteLine("受信")
    End Sub

    (2)受信データを取り込むために後半を以下の様にすると

    Private Sub ReciveCallBack(ByVal msg As Lawicel.CANUSB.CANMsg)
    '■■■CANデータ受信時■■■
    Console.WriteLine("msg.id")
    Console.WriteLine("msg.len")
    Console.WriteLine("msg.data")
    End Sub

    コールバック設定部
    nRet = Lawicel.CANUSB.canusb_setReceiveCallBack(h, AddressOf Me.ReciveCallBack)
    に"オーバーロード解決に失敗しました"といったエラーメッセージが出てしまいます。

    コールバック設定部かどこかで記述が不足している(あるいは間違っている)部分が
    あると思うのですが、残念ながら自分で解決できていない状態です。

    何卒アドバイスいただけますようよろしくお願い申し上げます。
引用返信 削除キー/
■33207 / inTopicNo.2)  Re[1]: Lawicel社 CANUSB コールバック関数に関して
□投稿者/ Hongliang 大御所(508回)-(2016/01/05(Tue) 19:14:22)
  • アイコン
    canusb_setReceiveCallBackが要求するデリゲートCANMsgCallbackDefは、
    Public Delegate Sub CANMsgCallbackDef(ByRef msg As CANUSB.CANMsgCallback)
    だそうですよ。コールバックに使おうとしているメソッドの引数が全然違いますね。
    
    あと、単純にそのままアンマネージに渡しているだけのようなので、
    このままだとコールバックがそのうちGCに片付けられることになるかと思います。
    デリゲートオブジェクトをフィールドに保持しておいた方がいいかと。
    Private m_Callback As Lawice.CANUSB.CANMsgCallbackDef
    Private Sub Open_Click(ByVal eventSender As Object, ByVal eventArgs As EventArgs) Handles Open.Click
        ' 略
        Me.m_Callback = AddressOf Me.ReceiveCallback
        nRet = Lawicel.CANUSB.canusb_setReceiveCallBack(h, Me.m_Callback)
        ' 略
    End Sub
    

引用返信 削除キー/
■33208 / inTopicNo.3)  Re[2]: Lawicel社 CANUSB コールバック関数に関して
□投稿者/ あらいぐま 一般人(2回)-(2016/01/06(Wed) 12:02:40)
  • アイコンHongliangさんアドバイス、本当にありがとうございます。

    > コールバックに使おうとしているメソッドの引数が全然違いますね。

    Private Sub ReciveCallBack(ByVal msg As Lawicel.CANUSB.CANMsg)
    '■■■CANデータ受信時■■■
     (略)
    End Sub

    上記メソッドの引数でしょうか。
    思い込みが強いためかこの引数をどう記述すべきかが判らないでおります。
    申し訳ございませんがご教示いただけましたら幸いです。

    > このままだとコールバックがそのうちGCに片付けられることになるかと思います。
    > デリゲートオブジェクトをフィールドに保持しておいた方がいいかと。

    > Private m_Callback As Lawicel.CANUSB.CANMsgCallbackDef

    ガベージコレクション防止するために、明示的に変数として宣言しておくという
    考え方で宜しいでしょうか。


引用返信 削除キー/
■33209 / inTopicNo.4)  Re[3]: Lawicel社 CANUSB コールバック関数に関して
□投稿者/ Hongliang 大御所(509回)-(2016/01/06(Wed) 12:47:49)
  • アイコン
    > Private Sub ReciveCallBack(ByVal msg As Lawicel.CANUSB.CANMsg)
    > '■■■CANデータ受信時■■■
    >  (略)
    > End Sub
    > 
    > 上記メソッドの引数でしょうか。
    
    はい。
    
    > 思い込みが強いためかこの引数をどう記述すべきかが判らないでおります。
    
    Delegateが定義しているのと同じ引数が必要です。ByRefなCANMsgCallbackですね。
    
    >>Private m_Callback As Lawicel.CANUSB.CANMsgCallbackDef
    > 
    > ガベージコレクション防止するために、明示的に変数として宣言しておくという
    > 考え方で宜しいでしょうか。
    
    フィールド(メンバ変数)として、です。
    変数は変数でもローカル変数(メソッド内部で定義する変数)であれば、メソッドが終了したらGC対象になるので。
    フィールドであれば、その保持するオブジェクト(多分Formかな?)が存在している間はGC対象になりません。
    
    通常はGCがどうこうってのは考えなくて良いのですが、
    アンマネージに渡す場合、アンマネージ側は参照を管理しないので、
    フィールドに置いておかない場合GCが
    「もうこのデリゲートオブジェクトは誰からも参照されていないな」
    と判断して片付けられる可能性があります。

引用返信 削除キー/
■33210 / inTopicNo.5)  Re[4]: Lawicel社 CANUSB コールバック関数に関して
□投稿者/ あらいぐま 一般人(4回)-(2016/01/06(Wed) 18:18:50)
  • アイコンHongliangさんご教示ありがとうございます

    またご教示いただくにあたり貴重なお時間を割いていただきましたこと
    お礼申し上げます。
    #おそらくLawicel社のWebを見たりお時間を費やしていただいていると思います。

    > Delegateが定義しているのと同じ引数が必要です。ByRefなCANMsgCallbackですね。

    ありがとうございます。全く理解できていませんでした。
    データ受信は確認しましたので、自分なりに理解した上で再度投稿させていただきます。

    Lawicel社のVBサンプルはタイマーイベントでデータをReadする例しか無かったので
    備忘録としてまとめておきたいと思います。

    > フィールド(メンバ変数)として、です。
    > 変数は変数でもローカル変数(メソッド内部で定義する変数)であれば、メソッドが終了したらGC対象になるので。
    > フィールドであれば、その保持するオブジェクト(多分Formかな?)が存在している間はGC対象になりません。

    なるほど、メソッド実行後のことも考える必要があるわけですね。
    本当にありがとうございます。

    取り急ぎお礼まで。本当に助かりました。
引用返信 削除キー/
■33213 / inTopicNo.6)  Re[5]: Lawicel社 CANUSB コールバック関数に関して
□投稿者/ あらいぐま 一般人(5回)-(2016/01/12(Tue) 16:40:10)
  • アイコンHongliangさんにご教示いただき、下記コードで動作を確認出来ました。
    Hongliangさん、本当にありがとうございました。

    ※コールバック関数を利用してCANデータ受信内容をテキストボックスに表示する
     Lawicel社 CANUSBアダプター使用

    ※環境:Lawicel社提供dll(canusbdrv.dll version 2.0.2)を使用 
        Windows7(32bit) VisualBasic2012

    Private m_Callback As Lawicel.CANUSB.CANMsgCallbackDef

    Private Sub Open_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles Open.Click
    '■■■CANポート オープン処理■■■
    Dim nRet As Integer

    '///指定されたデバイス(シリアル番号を指定)をオープンする
    h = Lawicel.CANUSB.canusb_Open("LWZ55LBC", "500", Lawicel.CANUSB.CANUSB_ACCEPTANCE_CODE_ALL, Lawicel.CANUSB.CANUSB_ACCEPTANCE_MASK_ALL, 0)

    '///正常にポートがオープンできたらコールバックを設定
    If (h <> 0) Then
    Me.m_Callback = AddressOf Me.ReceiveCallBack
    nRet = Lawicel.CANUSB.canusb_setReceiveCallBack(h, Me.m_Callback)
    End If

    End Sub

    Private Delegate Sub ReceiveCmdToTextBox(ByVal RcvCmd As String)

    Private Sub ReceiveCallBack(ByRef RxMsg As Lawicel.CANUSB.CANMsgCallback)
    '■■■受信メッセージの格納及びテキストボックス表示■■■
    Dim iByteArray() As Byte
    Dim iData As String
    Dim sb1 As New System.Text.StringBuilder

    '///エンディアン変換
    iByteArray = BitConverter.GetBytes(RxMsg.data)
    iData = BitConverter.ToString(iByteArray).Replace("-", String.Empty).Substring(0, RxMsg.len * 2)

    '///受信メッセージ格納
    sb1.Append(RxMsg.id.ToString("X3")).Append("_").Append(RxMsg.len.ToString("X1")).Append("_").Append(iData).Append(vbCrLf)

    '///受信メッセージをテキストボックスに追記する。
    Dim args(0) As Object
    args(0) = sb1.ToString
    BeginInvoke(New ReceiveCmdToTextBox(AddressOf Me.RcvCmdToTextBox), args)
    End Sub

    Private Sub RcvCmdToTextBox(ByVal RcvCmd As String)
    '■■■受信メッセージをテキストボックスに表示■■■
    If IsNothing(RcvCmd) = False Then
    Txt_RcvCmd.Text = RcvCmd
    End If
    End Sub



引用返信 削除キー/
■33214 / inTopicNo.7)  Re[6]: Lawicel社 CANUSB コールバック関数に関して
□投稿者/ あらいぐま 一般人(6回)-(2016/01/12(Tue) 16:42:06)
  • アイコン連続投稿、申し訳ございません。
    ”解決済み”のチェックを失念したため、再投稿致しました。
解決み!
引用返信 削除キー/



トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

Mode/  Pass/


- Child Tree -