2012-02-01 4 views
7

私はC#でライブラリを作成していますが、非同期にする必要があります。通常、一連のDLL関数を公開し、入力パラメータを受け取り、終了すると値を返します。しかし、入力を引き継ぎながらすでにストリーミングバックアウトを開始しているライブラリ関数(C++/Delphi/etcから呼び出し可能)を作るにはどうしたらよいですか?ハードウェアデバイスからデータをストリーミングする非同期API

今私が見る唯一の解決策は、DLL呼び出しの代わりにソケット/パイプ/ etcを使用して通信することです。

誰かが通常のDLL呼び出しでこれを行う方法の例がありますか?

+0

本当にあなたが何をしているかによって異なる...あなたは、次の入力チャンクが必要なときにDLLによって呼び出される関数へのポインタを交換することもできます...共有メモリとグローバルmutexを使ってデータを交換できますあなたは本当にもっと多くの詳細を与える必要があります。 – Yahia

+2

ここにはさまざまなオプションがあります - それは、あなたが得た出力の種類と入力がどのようなものかによって部分的に異なります。私が「非同期」と聞くと、私はワンショットの非同期呼び出しを考える傾向があります。「ここにいくつかの入力があり、準備ができたら出力を出す」ということですが、ストリーミング・ソリューションのほうが望ましいかもしれません。より多くの文脈が役に立つでしょう。 –

+0

1つのオプションは、出力データのチャンクを処理するためにコールできるコールバックパラメータを関数に持たせることです。しかし、APIの中で最も便利ではないかもしれません。より自然な方法では、ある種のイテレータオブジェクトを返すことになりますが、その入力がどこから来るかによって、ライブラリをより複雑にすることができます。 – millimoose

答えて

0

を与えられている、DLLは、いくつかのUSBインタフェースを介してオーディオ送信し、DLLがマイクインターフェースから一部のオーディオをキャプチャキャプチャされたオーディオをアプリケーションに戻す必要がありますこれと、呼び出しは私が通信チャネルのためのいくつかのオプションを参照してくださいrahter異なる言語で書かれたことができるという事実に基づきなど

DLLへのオーディオのds:

  • TCP/IP(デスクトップ」に応じて、ファイアウォールの設定は、」など、これは問題かもしれない!)
  • パイプイベント/イベントハンドラのコールバックと
  • DLLと
  • COMオブジェクトこれは、すべての言語のために働いて得るために少し難しいだろうが、
  • グローバルミューテックスを持つ共有メモリは、それがために、それは本当に簡単になりますので、私は次のようなアプローチが好き
1

直接的な非同期ライブラリ呼び出し(System.dllにあります)の良いモデルは、WebClient.DownloadStringAsyncです。このメソッドはUriから非同期にダウンロードし、終了するたびにDownloadStringCompletedイベントを発生させます。

ライブラリーでも同様に、現在のスレッドをブロックせず、ライブラリーにデータが入るたびにFooDataReceivedイベントが発生し、計算が終了するたびにFooCompletedイベントが発生します。

+1

OPは双方向の非同期を望んでいることを考慮していません - 彼は入力非同期も受け取りたいと思っています... – Yahia

0

これにはいくつかの方法があります。ほとんどの言語では、スレッドまたはディスパッチャーを使用してメソッドに非同期呼び出しを行うことができます。一般に、あなたがdllをre-entrant(同時に複数のスレッドを処理することができる)にする限り、呼び出し環境は非同期部分を処理することができます。

ただし、非同期呼び出しをAPIに書き込むことは可能です。これを行うものの例はWCF client proxiesです。

0
  • あなたが入力と出力の両方が非同期になりたいので、あなたは ワーカースレッドが必要になります。両方を気にすることはできません、入力スレッド、また出力を遮断することができ を取って1どちらの場合仕事をする。

  • あなたは既にパイプを介して通信を考えたが、なぜパイプではなく内部strcutureを使うのか?

  • だから、あなたが入力時にこのロックフリーキューを持っているが、出力に別のものとワーカースレッドが

  • ワーカースレッドがoutqueueにそれを置く、それを処理し、inqueueから入力を受け取り

  • 入力キューが空になった場合は、ワーカースレッドが上のクランチには何もしていますので、彼は、入力キューはなってきての「より多くのデータを必要とする」イベントを発生させ、その後、ブロックは(一部)フル

  • ワーカースレッドの場合出力キューに何かを置くと、 "have moデータ」イベント再、および出力キューは、出力空間上の(完全に)完全な、彼のブロックになった場合に利用できるようになってき

  • あなたのAPIは、ノンブロッキングさ:入力を送信することも、出力を受け取るどちらもすることは、これまで

  • あなたのAPIが非同期であるがブロック:(イベント経由)通知は、呼び出し元のアプリケーションがDLLにオーディオを送信するOPからのコメントによると

0

(ポインタとミューテックスの名前を返すDLLから「セットアップ」機能を提供することにより、消費するアプリケーションのためにそれを緩和することができ)クライアント。

// your library 
class Foo { 
    public event EventHandler ComputeCompleted = (sender, e) => { }; 

    public void Compute() { 
     // kick off work on a background thread 
     // possibly using the BackgroundWorker object 
     var bw = new BackgroundWorker();  
     bw.RunWorkerCompleted += RunWorkerCompleted; 
     bw.RunWorkerAsync(); 
    } 

    private void RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { 
     ComputeCompleted(this, new object()); 
    } 
} 

// calling code 
Foo foo = new Foo(); 
foo.ComputeCompleted += Completed; 
foo.Compute(); 

private void Completed(object Sender, EventArgs e) { 
    // process the result here 
} 

要旨はすぐに返すライブラリ内のメソッドをキックオフということで、その後、処理が完了したイベント/デリゲート経由して、発信者に通知します。その後、必要に応じて実行をUIスレッドに呼び出すことができます。

明らかに、エラー処理はサンプルコードに含まれていません。

+0

と、C++や、delphiなどでどうやって使えますか? – Yahia

+0

@Yahia C++には、C#の構造を簡単に使用できる管理モードがあります。私は1995年以来、デルファイと何もしていないので、実際にはコメントできませんでした。 – AngryHacker

+0

はい、私はOPからライブラリがネイティブなものを含むいくつかの言語から使えるはずであることを理解しています。(Delphiはネイティブですが、COMを使うことができます)... – Yahia

関連する問題