• ベストアンサー

DLL(VC++で作った)で稼動中の計算の進捗状況をVBで知りたいのですが。

もともとCで計算していたものを,DLLにしました。 VBから普通に呼び出せるようにまでできるようになったのですが, できれば,結果だけでなく計算の進捗状況・途中結果なども知りたい思うようになりした。 どのようにすれば,このような機能を実装できるのでしょうか? ちょっとした計算に使うためにプログラムを書く程度なので, プログラミングやOSの仕様などはよくわからないのですが, VBで受け取れるイベントのようなものをDLLから送出したりできるのかなぁ? なんて考えて探してみたのですが,やはりよく分かりません。 VB側では結果を待機するループのようなものは回したくないので, イベントとして受け取れればなぁ~と思ったのですが。 説明がへたくそ&PCやプログラミングに詳しくないため 質問の真意が伝わりにくかったかもしれませんが, どんな些細なことでも結構ですので,解決法をご教授ください。 どうぞよろしくおねがいします。

質問者が選んだベストアンサー

  • ベストアンサー
  • honiyon
  • ベストアンサー率37% (331/872)
回答No.1

こんにちは、honiyonです。  方法は2つあります。  1.進捗を伝える関数を用意する。  2.進捗報告用のコールバック関数(機能)を用意する。  2は色々と難しいのですが、1は簡単に出来ると思います。  進捗報告関数は、今現在の計算具合を判断し、その結果を返します。  この関数をし、VBから一定時間ごとにその関数を呼び出す事で進捗具合を知ることが出来ます。  簡単な説明ですが参考になれば幸いです(..

pinko-iz
質問者

お礼

早速のご回答ありがとうございます。 >1.進捗を伝える関数を用意する。 ですが,これは 「VB側(上司)から一定時間ごとにDLL側(部下)に進み具合を聞きに行く」 というイメージでよろしいでしょうか? もしできることならば 「ある程度作業が進むたびにDLL(部下)がVB(上司)に進捗を報告する」 というようなイメージにしたいのですが…。 DLLがVBにイベントを送出できたらなぁ~という発想です。 >2.進捗報告用のコールバック関数(機能)を用意する。 ですが,ご想像の通り難しくて分かりません(笑) でも,もしかしてこれが,ぼくがやりたいと思っていることなのでしょうか? もしそうでしたら,よろしければアドバイス頂きたいのですが。 よろしくおねがいします。

その他の回答 (5)

  • mkii
  • ベストアンサー率40% (43/105)
回答No.6

DLLではなくActiveXとして作れば、イベントを送り出せますよ。

  • arata
  • ベストアンサー率49% (139/279)
回答No.5

今回は、VBでとのこと、がんばってください。 参考までに、下記のURL(「猫でもわかるプログラミ ング」)のWindows SDK編72章に(DLLでやっていませ んが)プログレスバーを出す例がありますので、 ご参考までに。

参考URL:
http://www.kumei.ne.jp/c_lang/
  • arata
  • ベストアンサー率49% (139/279)
回答No.4

具体的に、やり方は説明できないのですが、UNLHA32.DLLってDLL側で、プログレスバーを表示していますよね。 あのやりかたをすれば、VB側で処理しなくてもいいのではないでしょうか。 なんのたしにもなりませんね。 ごめんなさい。

pinko-iz
質問者

お礼

ご回答ありがとうございます。 >UNLHA32.DLLってDLL側で、プログレスバーを表示していますよね。 >あのやりかたをすれば、VB側で処理しなくてもいいのではないでしょうか。 そうだったんですか…。知りませんでした。 確かに,使う立場からしたらありがたい機能ですね。 でも,DLLでユーザインターフェースを提供するのって, なんだか難しそうですよね(笑) ちなみに,僕はコンソールアプリしか作ったことがないので, 計算はC,ユーザインターフェースはVBという安易な発想になってしまいました。 いずれは,「自分でプログレスバーを表示するDLL」にも挑戦してみようと思います。 どうもありがとうございました。

  • honiyon
  • ベストアンサー率37% (331/872)
回答No.3

こんにちは、honiyonです。  私の紹介した2の方法を実現するには、ポインタや関数について熟知している必要があります。 また、1から全部説明すると結構な量になるのでおおまかに説明します。  因みに、ここで紹介する方法は VBで出来るか分かりません(^^;  コールバック関数というのは、VBでいうイベントのようなものにあたります。  では、コールバック関数機能(?)を実装するかというと、   1.コールバック関数のポインタを取得する。   2.任意のタイミングで、取得したポインタを使ってコールバック関数を呼ぶ  以上です。  たったこれだけなのですが、実際にやろうとすると結構大変です。(ポインタ周りで)  別件ですが、大事な事を忘れていました。  #1の、1の方法にしろ2の方法にしろ、itohさんの仰るように非同期処理が必要になります。 これを実現するために、一般的には「マルチスレッド」というものを用います。 これもまた簡単そうでコールバック以上に難しい技術です。  計算処理を行いつつ、平行して進捗処理も行うために必要になります。  またかなりおおまかな回答ですが(^^;、参考になれば幸いです(..

pinko-iz
質問者

お礼

再びのご回答ありがとうございます。 一度ならず,二度までも… 本当に感謝しております。 >私の紹介した2の方法を実現するには、… 「コールバック関数」というのは自分で作るのですね。 僕は計算用にコンソールアプリしか作ったことがないのですが, WIN32-SDKとかを少しかじったときにCALLBACKというような キーワードがあったように記憶していて, 「なにやら難しいもの」「SDKやMFCをやらなけりゃ縁のないもの」と 勝手に(笑)思い込んでおりました。 コールバックというのは, 「VB(上司)が進捗を管理する部署(コールバック関数)を設置し, 仕事を部下(DLL)に渡す際, その部署への連絡先(コールバック関数のポインタ)を指示する」 というイメージでよろしいでしょうか? まだ実際に試していないので定かではありませんが, 最近のバージョンではVBでも関数のポインタを渡せるようになったそうです。 では,さっそく実際につくってみようと思います。 ほんとうに,どうもありがとうございました。

  • itohh
  • ベストアンサー率45% (210/459)
回答No.2

こんにちは。itohhといいます。 >VBから普通に呼び出せるようにまでできるようになったのですが これは、DLL内の関数を呼び出すと言うことですよね? このDLL内の関数は、非同期で実行できるのでしょうか? 普通にと言われているところを見ると、例えば、ファイル入力関数のInput関数の ように、入力が完了するまで関数が戻ってこないのですよね。 まず、非同期に実行できるようにDLL内の関数を作り替えなければなりません。 これは、マルチスレッドとかマルチプロセスと言われている作りにしなければ いけないと言うことです。 その次に、計算途中でVBプログラムにメッセージを投げなければいけません。 VBプログラムでは、このメッセージを受け取ってイベントを発生させます。 このあたりの解説は、MSDNライブラリーの「非同期通知イベントの提供」を 参照してください。

pinko-iz
質問者

お礼

ご回答ありがとうございます。 >MSDNライブラリーの「非同期通知イベントの提供」を参照してください。 「非同期」といういうキーワードがどんぴしゃりだったのですね。 系がVB-DLLではなかったですが,良いサンプルがのっていました。 どうもありがとうございました。 いずれ処理の分散化?並列化?を考えていたため, 実は既にスレッドをたてて計算しています。 プロセス間通信という言葉を聞いたことがあったので, マルチスレッド・マルチプロセスのところをいろいろ調べていたのですが, 調べ方が足りなかったようですね。いやはや。

関連するQ&A

  • VC++のDLLをVB6.0からVB.NETへ移行する方法

    はじめて投稿します。 今、現状VB6.0のプログラムで使用しているVC++のDLLを VB.NETで使用できるように、VB.NETのソースの改修をしています。 (開発環境は、VisualStudio.NET 2003) たいていのDLLは、DllImportを行うことで VB.NETから使用できることを確認しました。 /*--(例)------------------------------------------*/ Imports System.Runtime.InteropServices <DllImport("DLLTest.dll")> _ Private Shared Function DLLTestMethod() As Integer End Function /*------------------------------------------------*/ しかし、苦戦しているDLLファイルがあって、 そのソースを見ると、COMで実装されているようで、 コンパイルしたらタイプライブラリファイルが作成されています。 またDLLのレジストリも登録されているようです。 VB6.0でどう使われているか確認したところ、 そのDLLの参照設定をしていて、 "Public obj As New クラス名"でクラス宣言した後、 obj.関数名()で処理を行っています。 VB.NETでいろいろ試行錯誤してみましたが 参照設定はできるものの、その後で手詰まりになっています。 (参照設定しても、灰色になっているクラス名が存在するので 正しく設定できているかも怪しい状態) (1)----------------------------------------------- 参照設定後、オブジェクトブラウザから見えるクラスをNewして そのメンバ関数を使用する方法 -------------------------------------------------- (結果) レジストリ登録をしていないと 「CLSID{・・・}のCOMオブジェクトが有効でない」云々というエラーに。 それを受けて手動で該当するDLLのレジストリ登録を行った後だと 「オブジェクト参照がオブジェクトインスタンスに設定されません」というエラー。 (ということは、クラス生成に失敗している?) (2)----------------------------------------------- 上記のようにDllImportで実装する方法 (ちなみにそのDLLがエクスポートしている関数は DllCanUnloadNow, DllGetClassObject, DllRegisterServer, DllUnregisterServerの4つ) -------------------------------------------------- (結果) DllGetClassObject以外については関数を呼ぶことができている。 DllGetClassObjectは、引数設定に苦戦して今のところうまくいっていない状態。 (3)----------------------------------------------- インスタンス生成ができていないようなので どこかで調べて見つけてきたCoCreateInstance関数を使用する方法 -------------------------------------------------- (結果) これも引数に何を渡してよいかわからず試行錯誤中。 DLLの読み込みの時点でこけているかと予測して そのあたりが解決すればよいのかな・・・といろいろ試していますが WindowsプログラミングやCOMがよくわかっていないので 何が正解で何が間違っているのかさっぱりわからず、 周りに聞いても精通している人がいないためどうしようもなくなっています。 どんな些細な手がかりでもよいので 突破口になりそうなアドバイスがあれば教えてください。 よろしくお願いします。

  • VC++で作成したDLLをVBから呼ぶと戻り値が化けてしまう

    はじめまして。いつも勉強させていただいております。 VCは今回初めてやっておりますので当たり前の質問 になってしまうかもしれませんがご教授願います。 以下のような仕様でものづくりを行っております。 1.VBよりVC++で作成したDLLを呼び出す。 2.VC++で作成したDLL側ではパラメータより取得した   値を元に足し算をした結果を   戻り値にセットして要求元に返却する。 といった流れで考えています。 2の部分についてはExeを一度作成し実行させた ところDOS窓に値が表示されました。(printfで) しかし、正しくOUTPUTされた値がVB側の戻り値と して返却された時点で参照すると「-6348」 となっています。 なぜこうなってしまうのか原因がわからず投稿 させて頂きました。 ご存知の方、ご教授下さい。 ************************************************* VC++ DLL側のソース ************************************************* #include <windows.h> #define DLL_EXPORT __declspec(dllexport) extern "C" { DLL_EXPORT int add(int a,int b); } int add(int a,int b) { return a+b; } ************************************************* VB  DLL呼び出し元 ************************************************* Option Explicit Private Declare Function add Lib "C:\Program Files\Microsoft Visual Studio\test\Debug\test.dll" Alias "_add@8" (a As Long, b As Long) As Integer Private Sub Command1_Click() Dim ret As Long ret = add(1, 2) MsgBox ret End Sub 環境 OS:WinXP 言語:VC++6.0    VB6.0(SP6)

  • VB6.0で作成したデータ(配列に入った数値)をVC++に渡したい

    掲題の件ですが、 VB6.0ではアドレスを指定して、 メモリを書いたり読んだりすることが困難ということが分かり、 VBで計算した結果をVC++に渡して、VC++でアドレスを指定してメモリに書き込んだり、 読み込んだりするようにしようと考えています。 プログラミングは初心者なので、これが実現可能かどうかが分からないのですが、 調べると、VC++でDLLファイルを作ってVBで参照するという方法はあったのですが。 ・これは実現できるのか。 ・どこにどのようなコードを書けば良いか(同プロジェクト内に違う言語を存在させることは可能か。) ・受け手側はどのように記述すれば値を受けれるか 以上よろしくお願いします。 http://forums.belution.com/ja/vb/000/007/59.shtml このような問題がありました。

  • VBで作成したフォーム上に電卓アプリの計算結果を反映させたい

    現在VB6.0でプログラミングをしています。VBのフォームから電卓アプリを呼び出し、その計算結果をVBのフォーム上のテキストに反映させたいのです。 電卓をsehll関数で起動させることはできるのですが・・・。 現在ネットなどでいろいろ調べているのですが行き詰っています。 何かよい方法をご存知の方がいましたら教えてください。

  • DLL内のイベントをハンドリング

    VB2008にて、外部DLL(VB2008作成)を使用しようと考えています。 外部DLLの仕様書には、メソッド、イベント、プロパティが記載されており、 外部DLLの発生させるイベントをハンドリングしたいのですがうまくいきません。 「参照の追加」にてDLLを指定し、ソース内で該当DLLのクラスもインスタンス化し、 DLL内のメソッドは使用できています。 イベントに関して仕様書には Event001(Byval arg1,Byval arg2)、Event002(Byval arg1,Byval arg2)、Event003… このように記載されています。 該当DLLのインスタンス化したものをTestClassとして、 Public Event TestEvent Handles TestClass.Event001 という記載では駄目でした。 外部DLLのイベントのハンドリングについて、ご教授頂けましたら幸いです。

  • イベントの取りこぼしについて

    教えて下さい。 VBで構築したアプリケーションにおいて、無限ループ内で処理を判断し、実行するようなプログラム構築にしています。この無限ループ内に「DoEvents」をセットしています。これによりOSに溜まっている、各イベントを処理していると思うのですが、処理するイベントに取りこぼしは発生しないのでしょうか? 現在、A/Dボードを実装しており、2ms周期でVBのイベントが発生するようなソフトになっています。「DoEvents」実行時に、OS側が処理に要する時間は、キューに溜まっているイベント数×1回のイベント処理時間で単純に導けるものでしょうか? また、CPUのスペックを2倍にすると、単純に処理時間は半分と計算できるものでしょうか?

  • ループ制御と配列変数について

    VBでプログラミングを作っています。 値を入力して計算させ、返ってきた結果を足していくというものです。 普通ならループ制御でやるのですが、一回一回入力する値が違うためにボタンでスタートさせます。 この場合「スタートと計算が同じボタン」、「計測回数は決まっていない」ということからも、手詰まりになってしまいました。 ループと配列変数であろうことはわかるのですけども… 上記の要件を基に、計算結果を一回ごとに変数に入れて全て足すためには、どうプログラムを組めばいいでしょうか?

  • VB2005でで正しい計算結果が出ません。

    VB2005でで正しい計算結果が出ません。 こんにちわ。プログラミング初心者です。どうかよろしくお願いします。 緯度経度を変換する計算式をプログラムしたのですが、計算結果が間違って出力されます。 下にプログラムを書くのでどこがおかしいのか、またどうすれば正しい計算結果が求められるのかを教えてください。お願いします。 ちなみにTextBox22には 3601.4589 、 TextBox23には 13942.9930 のような数字が入っています。 Private Sub seriWork() Dim buffer, buffer2() As String Dim di1, di2, dk1, dk2 As Double '~通信に関するところなので中略します~ '~ここから先が計算です~ 'Dの緯度百分率変換表示 TextBox22.Text = dN di1 = Double.Parse(Mid(TextBox22.Text, 1, 2)) di2 = Double.Parse(Mid(TextBox22.Text, 3, 7)) TextBox14.Text = di1 + (di2 / 60).ToString() 'Dの経度百分率変換表示 TextBox23.Text = dE dk1 = Double.Parse(Mid(TextBox23.Text, 1, 3)) dk2 = Double.Parse(Mid(TextBox23.Text, 4, 7)) TextBox15.Text = dk1 + (dk2 / 60).ToString() Me.Invoke(New ReDelgate(AddressOf completed)) End If Loop Catch ex As Exception MessageBox.Show(ex.Message, "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error) Finally If SerialPort1.IsOpen = True Then SerialPort1.Close() End Try End If この計算の意図は、GPSレシーバーから受信される「3601.4589」のような形の座標形式を googl mapで表示できる座標に変換するものです。 たとえば、シリアルポートでGPSから受信した緯度が3601.4589 の場合は、「=36 + (1.4589 / 60)」と計算すると 36.024315 のような形になります。 あと、3601.4589 を 36と1.4589で分割するためにMidを使用しています。 /60は公式です。 上記プログラムだと 62.3333333 のような誤解答が出てきます。 どうか教えてください。お願いします。

  • VBからDLLへ多次元配列を渡す/配列の添え字

    C++で作ったdllにVBAから配列を渡して、計算結果を再びVBAに戻して、アウトプットはVBAで、ということをしています。(経験豊富な方への相談です。) 具体的には、渡したい配列の先頭アドレスをlong型で記憶し、そのlong型の配列を受け渡ししています。 ただ、ご存知の方が多いかもしれませんが、VBAとC++では配列の添え字の順序が逆になっており、非常に面倒です。どういうことかといいますと、 Dim array(0 to 4, 0 to 9) as long をdllに渡し、array(2,6)を参照したい場合、C++では(Cでの配列名をc_arrayとし、これに先頭アドレスを入れると)、 c_array[(4+1)*6 + 2 ]; としなければならないと思います。これをプリプロセッサで #define C_ARRAY(a,b) c_array[(4+1)*b + a] としたらVBでの配列の感覚で扱えますが、この擬似配列C_ARRAY(a,b)を関数に渡すときなどは結局同じ混乱が再び生じることになってしまいます。 これを、何らかの方法で、簡潔に解決することはできないものでしょうか? VBA(エクセルを念頭においています)のほうで配列の添え字の順序をC++のそれに沿うように変更できたりしたら非常にうれしいですが、無理でしょうか?

  • <vb.net> 内容変更しても以前のTEXTなどが残っている?

    Vb.net 初心者です。 単純ですが、困っています。こんなことがあるのでしょうか。 プログラミングの内容変更をして、何度も保存をしました。 FormulaやTextなどを変えてみても、たとへば”Today"を”Yesterday"にして他の計算の確認のため、Debugをしてもまだ、”Yesterday" のままです。となると変更後の計算結果が正しいかどうかわかりません。ComputerそのものはUSA仕様なので、言語のEncodingの問題でしょうか。もちろん、変更しないところはそのまま読み取っていて、btnCalculateやbtnExitなどはきちんと動きます。

専門家に質問してみよう