4

現在のプロジェクトでは、DBus (1.6.n) を使用しています。主に C++ から共有メモリ モードでアクセスされますが、これは非常にうまく機能します。

現在、C# プログラムから同じ DBus にアクセスしようとしています。

最初に試してみるために、見つけた最新バージョンの dbus-sharp をダウンロードし、ダウンロードに含まれているデーモンを起動して、テスト C# アプリから接続できるかどうかを確認しました。

接続を確立するたびに、デーモン コンソールは通信中であることを示しますが、接続上のメソッドにアクセスしようとするとすぐにエラーが発生します。

「アクセスが拒否されました: DBus.BusObject」

これが私が試したコードです。

        DBus.Bus dBus = null;
        try
        {
            //input address comes from the UI and ends up as "tcp:host=localhost,port=12345";
            //dBus = new Bus(InputAddress.Text + inputAddressExtension.Text);
            //string s = dBus.GetId();
            //dBus.Close();

            //DBus.Bus bus = DBus.Bus.System;
            //DBus.Bus bus = Bus.Open(InputAddress.Text + inputAddressExtension.Text);
            //DBus.Bus bus = DBus.Bus.Session;
            //DBus.Bus bus = DBus.Bus.Starter;

            var conn = Connection.Open(InputAddress.Text + inputAddressExtension.Text);
            var bus = conn.GetObject<Introspectable>(@"org.freedesktop.DBus.Introspectable", new ObjectPath("/org/freedesktop/DBus/Introspectable"));

            bus.Introspect();

        }
        finally
        {
            if(dBus != null)
                dBus.Close();
        }

コメント付きのコードでも、最終的には同じエラーが発生します。

私はデバッガーをステップ実行しましたが、常に TypeImplementer.cs の次のコードに到達します。

public Type GetImplementation (Type declType) { Type retT;

        lock (getImplLock)
            if (map.TryGetValue (declType, out retT))
                return retT;

        string proxyName = declType.FullName + "Proxy";

        Type parentType;

        if (declType.IsInterface)
            parentType = typeof (BusObject);
        else
            parentType = declType;

        TypeBuilder typeB = modB.DefineType (proxyName, TypeAttributes.Class | TypeAttributes.Public, parentType);

        if (declType.IsInterface)
            Implement (typeB, declType);

        foreach (Type iface in declType.GetInterfaces ())
            Implement (typeB, iface);

        retT = typeB.CreateType (); <======== Fails here ==========

        lock (getImplLock)
            map[declType] = retT;

        return retT;
    }

C# からの DBus へのアクセスに関する有用な例やドキュメントは見つかりませんでした。これに関する最近のエントリはどこにもないように思われるため、他の誰もこれを試していない可能性があります。

テストプログラムと同じフォルダーでデーモンを実行しています。Windows で実行しているため、デーモンは tcp 設定をリッスンしています。

string addr = "tcp:host=localhost,port=12345";

これはダウンロードに含まれている例なので、簡単に実行できると思いましたが、残念ながらまだうまくいきません。

他の誰かがここにいて、パズルの次のピースを知っていますか?

どんなアイデアでも大歓迎です。

4

2 に答える 2

1

コメントも回答もなかったので、質問してから見つけた情報で質問に答えます。

DBus への有用な C# インターフェイスはないようです。(役に立つとは、機能するものを意味します!) 私が見つけた唯一の情報または例は最新のものではなく、機能するインターフェースを提供するために努力が費やされているようには見えません。

Windows サービスとして記述された C++ 実装を使用して DBus とやり取りすることにしました。C# プログラムはサービスを介して DBus にメッセージを送信します。これは問題なく動作するようで、ビジネス ニーズを満たします。

C# から DBus を動作させることができないことに失望していますが、Windows で動作するサービス バスの実装はたくさんあるので、将来的には DBus の代わりにそれらを実装することを検討します。

Windows で C# から DBus にアクセスするための実用的で文書化された解決策を誰かが思いついた場合、私はそれを見てみたいと思います。

于 2012-12-18T10:13:28.183 に答える
0

新しいテスト プロジェクトを作成し、dbus cs ソース ファイルをメイン プロジェクト アセンブリに追加すると、同じエラーが発生しました。動的に作成されたアセンブリで IBusProxy 型が動的に作成されたときでした。

asmB = AppDomain.CurrentDomain.DefineDynamicAssembly (new AssemblyName ("NDesk.DBus.Proxies"), canSave ? AssemblyBuilderAccess.RunAndSave : AssemblyBuilderAccess.Run);
modB = asmB.DefineDynamicModule ("NDesk.DBus.Proxies");
......
retT = typeB.CreateType ();

現在実行中のアセンブリが、作成されたアセンブリに適していないことが原因だと思います。そして、コンパイルされた NDesk.DBus.dll プロジェクトに追加すると、このエラーは消えました。

于 2014-08-04T06:29:35.600 に答える