0

C/C++ で記述された Dll を使用して、CAN ネットワーク (車内のネットワーク) のメッセージを取得するツールを c# で作成しています。この dll は、COM インターフェイスとして使用できます。

私の c#-formclass は、これらの COM インターフェイスの 1 つを実装しています。そして、他の変数は、これらの COM インターフェイスを使用してインスタンス化されます (すべてが完璧に機能します)。

問題: 私の C# フォームが実装するインターフェースには、3 つの抽象関数があります。これらの関数の 1 つは、dll によって呼び出され、自分で実装する必要があります。この関数では、COM タイプのフォーム全体の変数のプロパティを取得したいと考えています。

COM ライブラリは CANSUPPORTLib です

フォーム全体の変数:

private CANSUPPORTLib.ICanIOEx devices = new CANSUPPORTLib.CanIO();

この変数もフォーム全体であり、デバイス変数を介して取得されます。

canreceiver = (CANSUPPORTLib.IDirectCAN2)devices.get_DirectDispatch(receiverLogicalChannel);

dll によって呼び出され、c# で実装される関数

    public void Message(double dTimeStamp)
    {
        Console.WriteLine("!!! message ontvangen !!!" + Environment.NewLine);

        try
        {
            CANSUPPORTLib.can_msg_tag message = new CANSUPPORTLib.can_msg_tag();
            message = (CANSUPPORTLib.can_msg_tag)System.Runtime.InteropServices.Marshal.PtrToStructure(canreceiver.RawMessage, message.GetType());
            for (int i = 0; i < message.data.Length; i++)
            {
                Console.WriteLine("byte " + i + ": " + message.data[i]);
            }
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
        }
    }

エラーは次の行で発生します。

message = (CANSUPPORTLib.can_msg_tag)System.Runtime.InteropServices.Marshal.PtrToStructure(canreceiver.RawMessage, message.GetType());

エラー:

Unable to cast COM object of type 'System.__ComObject' to interface type CANSUPPORTLib.IDirectCAN2'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{33373EFC-DB42-48C4-A719-3730B7F228B5}' failed due to the following error: No such interface supported (Exception from HRESULT: 0x80004002 (E_NOINTERFACE)).

注: 必要なメッセージを 100 ミリ秒ごとにチェックするタイマー クロックを使用することは可能です。メッセージは、今とまったく同じ方法で取得されます。このタイマーは、フォームの開始時に開始されます。このチェックは、Message(double) が変数を true に設定した (メッセージが到着した) 場合にのみ行われます。

メッセージ機能でタイマークロックが開始されると、上記と同じエラーが発生します

フォームの開始時に別のスレッドを開始することもできません。

COM-interop の経験がある人はいますか?

このタイマーのとき

4

1 に答える 1

0

Messageを作成したスレッドとは別のスレッドで呼び出されるのだろうかcanreceiver

のスレッドモデルを知っていますCANSUPPORTLib.CanIOか? アパートメント スレッドの場合は、メイン UI スレッドからMessage何らかの方法で呼び出されたスレッドへの参照をマーシャリングする必要がある場合があります。

または、C++ dll のソース コードを変更できると仮定し、他のスレッド要件と制約に応じて、それをフリー スレッドに変更できます。この場合、オブジェクトはマーシャリングなしで複数のスレッドから同時にアクセスできます。

于 2010-03-19T07:48:40.000 に答える