🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

3回答

884閲覧

C++CLLを裏で連続動作させるには。

ParaParaDance

総合スコア56

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2019/12/23 02:14

編集2019/12/23 02:20

外部I/Fからのデータを受け取るC++ dllを作り、C#側から呼び出し、WindowsのText Boxに表示するプログラムを作っています。

【試した方法】
C++dllを呼び出す度にデータを読み出すようにし、C#側でDLLをTimerメソッドに入れて定期的にデータを読んでくる。 ※以下のコードで成功しました。

int __stdcall GetData() {     static int buff;     oApi.Receive(0, &MSGbuff); /外部I/Fからデータを読み取るAPI     buff = MSGbuff[0];     return buff; private void timer1_Tick(object sender, EventArgs e) {tBox_Angle.Text = Convert.ToString((short)DLLimpo.GetData());}

しかし、この方法では、I/Fデータと同期がとれているわけではないので、
受信漏れが発生します。

【試したい方法】
そこで、C#側のTimerで読んでくるのではなく、C++DLLを裏側で動作させ、DLLがデータを受信したら、それをC# プロパティに設定し、イベントを発生させる方法にしたいです。

C#でDLLを連続させるには、 Form1_LoadにDLLを入れればいいのでしょうか?
試しでDLLの中をLoopにし、 Form1_Loadにセットし、返り値をBufferに入れてTimerで定期的に取りに行くようにしてみたんですが、動きませんでした。
※同期をとることではなく、ただ裏で回せるために試したものです。

int __stdcall GetData() {     static int buff;     while(1){     oApi.Receive(0, &MSGbuff); /外部I/Fからデータを読み取るAPI     buff = MSGbuff[0];     return buff;}

DLLを裏で動作させることや動機を取る方法など、アドバイスをお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

データを能動的に取りに行くのか、勝手に送られてくるデータを受け取るのかちょっと明確でないのですが、受信漏れの話をしている点から前者と想定します。
推測するにハードウェアからの信号受信か何かですかね。

また
oApi.Receive(0, &MSGbuff);
はデータを受信するまで返ってこない設計をしている前提でお話します(この前提が成り立たないとそもそも成立しないので)

恐らくは周期的にデータが飛んでくるイメージがあり、Timerを使っているのかと思いますが、ここはTimerではなくTaskを立てて常時受付するべきです。
従ってwhile永久ループはC++側ではなくC#
のTask内に記述します。
Taskはデータを受け取ったら速やかにキューなどをlockしてデータを追加するだけのシンプルな処理とし、可能な限り受付不可な状態を避けるようにしましょう。

データの受信間隔が現実的な値であれば問題なく動作すると思います。

それでも受信漏れが問題になるようなら、それはもうoApi.Receive(0, &MSGbuff)の設計が悪いか原理的に不可能なレベルのことを要求しているかのどちらかかと思います。

投稿2019/12/23 03:34

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

こんにちは。

この手の問題は、oApi.Receive(0, &MSGbuff);の作り方の問題の場合が多いです。
この関数を呼び出していない時に外部I/Fから受信があったらどうなりますか?
その場合でも全ての(複数の受信が発生しても)受信データをきちんと取得できる設計になっていれば、取りこぼすことは無い筈です。
そうでない場合は、どんなに頑張ってReceive()関数を呼び出したとしても、例えばデータ受信後return処理している最中に次の受信が発生すると取りこぼします。

投稿2019/12/23 02:30

編集2019/12/23 02:30
Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ParaParaDance

2019/12/23 02:46

こんにちは、 アドバイス有難うございます。 確かにそうですね。APIの以前にSerial PortのIvent処理段階での問題ですね。それがちゃんとBuffering出来ていれば、Timerで取りに行ってもデータ漏れはないということでしょうか。
Chironian

2019/12/23 06:37

その通りです。
guest

0

たんにウィンドウを非表示にして動かしておけば済む話じゃないでしょうか。

投稿2019/12/23 02:21

y_waiwai

総合スコア88038

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ParaParaDance

2019/12/23 02:29

すみません、ウィンドウを非表示するってどういう意味でしょうか。 Window Form Appicationで常に値を表示させたいですが、それを非表示にするということですか??
y_waiwai

2019/12/23 02:45

C#側で動かし続けるなら、裏で動作させるとか考えなくていいのでは? DLLに値を読みに行ったタイミングでデータを取得してくればいいだけの話で。
ParaParaDance

2019/12/23 03:42

意味が分かりました。C#をループの主体で動かすという話ですね。 有難うございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問