- - PR -
アンマネージのC++でメンバクラスをもちつつ、VBから利用できるソフトの作り方(LinuxSquareより移動しまし
投稿者 | 投稿内容 | ||||
---|---|---|---|---|---|
|
投稿日時: 2005-03-26 09:18
いま、作っているソフトで、基本の仕組みとして、特殊なデータベースが必要なのですが、どういう形でくみ上げていくかテスト中です。なお、本来のアプリケーションは、VBで概略出来上がってデータがメモリ上のみなら速度もなんとか合格しています。次に、2〜100GB程度のデータを256MBクラスのマシンでそこそこの効率で処理できればOKなのですが、アプリの性格を利用した特殊DBを作ると簡単に解決できそうと、踏んでいます。
その場合の構成を思案中なのですが、ご意見をお願いします。 1案 VB→マネージC++→[DLLImport]→アンマネージC++ <良い点>: ○マーシャリング機能が使える。(今回は、渡すデータが限られているので、MSの用意しているマーシャリング機能は使わなくて済む。) ○将来、マネージC++とアンマネージC++の関係が変わっても、[DllImport]ではっきりと区切られているので、MSが差異を吸収する仕組みを提供してくれる可能性が大きい。 ○もしかしたら、アンマネージC++で、Staticであればメンバークラスを使える。(この辺が分かっていないのですが、メンバクラスをもつアンマネージクラスをVBから使えるようにするにはどうしたら、いいのでしょうか?) <悪い点> ○[DLLImport]部分で、2.8Gのマシンで20MSくらい直接Callよりも余分にかかる。 (直接のCallは1MS程度と思われる)、[DllImport]の使用は何百万回程度のLoopの中では耐えられない。したがって、アンマネージ部分を極大化して、[DllImport]を減らさないといけない。すると、アンマネージDLLの中で、クラスを定義して使ったりできるのか(Staticの制限つきであれ)実際のところがわかっていなくて、教えていただきたいところです。 2案 VB→マネージC++→アンマネージC++ [DllImort]を使わないという意味です <良い点> ○マネージから、アンマネージの関数を呼ぶ時間が短い。 ○VBからはマネージC++はDLLというものの、実際はフルに、メンバークラスをもち、あたかも通常のアプリのように、プログラムできるので、ある程度の規模のソフトを作る場合に、急に関数思考の、昔戻りを強要されないですむ。 <悪い点> ○マネージからアンマネージを呼ぶ時間は短いといっても、アンマネージのプログラム間でのCall時間に比して非常に長いのかも知れない。(測定すれば分かりますが、理論的に分かるほうがありがたいので、ご存知の方あれば、レスお願いします) ○将来マネージとアンマネージの関係が変わった時に、すべてを見直さないといけない。変わる理由は、マネージC++が変わる(MSのVersionUp)、およびアンマネージC++が変わる(たとえば、ボーランドやインテルのC++への私の乗り換え)こちらの場合でも、[DllImport]相当の仕組みを自分(と言うより、たとえばインテルが提供するソフト)で且つ20MSも時間を使って、置き換えることで、乗り換え問題が解決可能です。 ○アンマネージの側で、メンバークラスを持つことは、不可能と思います、すこしやってみましたが、Staticな変数でも、スコープがマネージとアンマネージにわたってしまうため、キチンと定義しきれないと思いました。そのため、アンマネージ側はクラスというより、関数思考で開発が必要です。したがって、断片的な処理(たとえば100MBのバファーを0で埋めるなど)をアンマネージ側でさせることになります。 案3 VB→メモリ→別プロセスのマネージC++とアンマネージC++の組み合わせ。 <良い点> ○DLLにまつわる、諸問題が一切ない。通常、DBはこの形に似た形で提供されており一般的。 <悪い点> ○仕組みがすこし複雑になる。 ○VBからのCall時間がかかりそうに思われる。 どなたか、このあたりで、非常に高速IPCの仕組みをヒントいただけるとありがたいです。 以上、一番の疑問はアンマネージのC++でメンバクラスをもちつつ、VBから利用できるソフトの作り方ということで、どんなご経験でも、直感でも、ヒントいただけるとありがたく、よろしくお願いします。 | ||||
|
投稿日時: 2005-03-27 08:22
自己レスです
訂正です。[ImportDll]の処理時間は、連続して10回読んだあとは、20MSから、急に1MSに減りました。2.8GHのマシンでは、1MSといえども1000命令ほどかと思いますので、20MSの理解に苦しんでいました。 JIT(ジャストインタイム)コンパイル時間は2回目からはなくなると勘違いしていました。訂正ならびに、どんなタイミングでなくなるか、ご存知の方のご返答お願いします。 | ||||
|
投稿日時: 2005-03-27 11:01
VBってVB.Netでしょうか? マネージC++との親和性がいいと書いてあるのでたぶんそうなんでしょう。
VB.Netで直接ImportDllしてはいけないのでしょうか? Declare Auto Function MBox Lib "user32.dll" _ Alias "MessageBox" (ByVal hWnd As Integer, _ ByVal txt As String, ByVal caption As String, _ ByVal Typ As Integer) As Integer または Imports System.Runtime.InteropServices <DllImport("KERNEL32.DLL", EntryPoint:="MoveFileW", SetLastError:=True, _ CharSet:=CharSet.Unicode, ExactSpelling:=True, _ CallingConvention:=CallingConvention.StdCall)> _ Public Shared Function _ MoveFile(ByVal src As String, ByVal dst As String) As Boolean End Function _________________ えムナウ Microsoft MVP for Visual Developer - C#,2005/01-2007/12 えムナウのプログラミングのページ Blog1 Blog2 | ||||
|
投稿日時: 2005-03-27 11:30
諸農です。
質問1:アンマネージド C++ は何をするんですか? 質問2:特殊データベースはVB.NET側で作成・操作するんですか? 質問3:2〜100GB程度のデータっていうのは前述の 特殊データベースとは別のものですか?
えムナウさんが言われている通り、DllImportするラッパークラスを 作成してアンマネージドC++をVB.NETから直接利用すればいいのではないですか。 --追加-- こんなの見つけました。 参考になるかと思います。 Designing .NET Class Libraries: Understanding Interoperability _________________ 諸農和岳 Powered by Borland Delphi/C++Builder & Microsoft VS.NET [ メッセージ編集済み 編集者: Jubei 編集日時 2005-03-27 11:46 ] | ||||
|
投稿日時: 2005-03-28 08:28
えむナウさん Jubeiさん ありがとうございます。
UnManagedCodeを直接呼ぶ議論の前に、もう少し状況を説明するためにも、Jubeiさんのご質問にお答えします。 1.UnManaged Codeで何をするか? 基本的に、DBの機能の中でも、Buffer関係の機能をさせるつもりです。大きなメモリをアロケーションし、それを、イニシャライズしたり、たんなるByte配列を、Pointerの構造として捕らえて、上位のIndexから、下位のIndexやデータレベルにポインターを追いかけたり、メモリにあるバッファーを優先順位によって、吐き出したり、(Pageingの様な機能です)今回のDBは、破棄やUpdateがなくて、最初に一度書くとあとは読む操作しかありません。この特徴はバッファー管理には都合が良いので、特殊DBを作って速度を市販DBの10倍とかやれそうなので挑戦しています。Cとかアセンブラーの感じで、作るような部分です。将来、IntelのC++に魅力(速度で)を感じています。 2.DBはVB(えむナウさんすみません。VisualBaicです)でWriteやReadの命令を出しますが、初期化、バッファーのアサインなどは、今のところ、マネージC++から行い、必要なところだけ、UnManaged Codeに渡そうと思ってます。DBはアプリに3個くらいしか必要なく、エンジンはみな同じですが、KEYの並び順の判定ソフトが違うとかの差異があり、そのような制御はManagedC++とおもってました。 3.2〜10GBというのが特殊DBのデータ量です。 で、元に戻って、VBから直接呼ぶのは、今にして思えばいいかもしれません。整理すると: 案4 VB→[ImportDll]→UnManaged Code <良い点> ○1段階Callのネストが減る。 そこを捕らえると、高速且つ、SolutionとしてSimple。 ○今日、やってみてわかったのですが、UnManagedのDLLのXXX.cppで単に、static にメンバクラスを宣言した場合、宣言されたメンバクラスは、さらに自分のメンバクラスを宣言する時は、要注意にしても、基本的に、あまり極端なことをせずにObjectを使ったプログラミングができる。 ○私の経験として、ManageC++はほとんどないので(DLLのWrapper程度)、予期せぬ工数が発生するリスクがなくなる。 <悪い点> ○皮肉ですが、利点は欠点です。1段階のネストが減る。いわば、VBとUnmanagedCodeの直接結合で、何らかの状況で不具合のあったときに、逃げ道がない。今、一番怖いのは、MSのVersionUpです。その時に間にWrapperをいれるのなら、基本構造として、がっちり、作っておきたいと思います。またIntelのC++に変える時もなにかと間があるのが良いような、いわば常数をコードでなくファイルに間接化するような気分はあります。 ○常にImportのOverHeadがかかる(案2が VB→ManageC++→UnManage で間にImportが入らないので、この点では一番良い) Jubeiさんの教えていただいた、MSのサイトには他にも、基本的な説明が多くありますので、3日くらいはかけて、勉強します。あとで、アーキテクチャーの理解不足から多大なロスが発生するのは、プログラマーの責任重大と思いますので。 また実測などを含めて検討したいと思います。 えむナウさん Jubeiさん また他のかたでもご意見お願いします。 ありがとうございました。 | ||||
|
投稿日時: 2005-03-28 21:38
諸農です。
VBと言うのは、VB.NETではなくVB6以前のことだったのですね。 であれば、私の提示したサイトは無意味かと思います。 UI部分に関わるところをレガシなVisual Basicで作成し、データ操作に関わる部分はアンマネージドな C++ で作った方がいいのではないでしょうか。今回のパターンであれば、無理に.NETにこだわる必要なんて無いと思います。 というか、なぜ.NETが候補に挙がっているのかがまったく判りません。 _________________ 諸農和岳 Powered by Turbo Delphi & Microsoft Visual Studio 2005 十兵衛@わんくま同盟 http://blogs.wankuma.com/jubei/ | ||||
|
投稿日時: 2005-03-29 17:07
Jubeiさん
すみません、VB.NETの間違いです。基本的な言葉も良く分かってなくて、友人と戦略ゲームのソフトを作るので、プログラマ担当をやっていますが、昔は、Windows系でなかったもので、言葉も分からぬ身ですが、それなりに入れ込んでプログラムしていますので、あきれずに付き合ってやってください。 それから、教えていただいたMSのサイトに、やはりJITコンパイルは最初の1回目だけとありました、12回とかやっていると、PlatFormInvokeが急に20MSから1MSに早くなるのは、不思議です。Inline化するためのTriggerがかかるのかなと思ってます。Performanceには、きびしいソフトなので、この辺の、奇妙な振る舞いは、何から来るか、近い将来分かっている必要がありそうです。ご存知のかた、教えてください。 | ||||
|
投稿日時: 2005-03-30 07:33
まず、読むのに苦労してまして 人のこと言えないですけど、空白を入れて分けましょうね。
今できていること: A.VB6で作成した、アプリケーションソフト 作成するもの: 1.Aのアプリケーションで使用するデータベースソフト 2.実際のデータは2〜100GBが見込まれる 3.実機はPen.4 2.8GHz Mem.256MBの予定 4.スピードを優先し、VC++6またはVC++.NETで作成したい 聞きたいこと: *作成するDBをどのような形で作り、どのように呼び出せばよいか 考えたこと: 1.VB.NET:Managed C++:dllimport:UnManaged C++ ○自動でマーシャリングされる ○???(意味不明) ○???(意味不明) ×Managed C++:UnManaged C++間で、20msec余計にかかる 2.VB.NET:Managed C++:UnManaged C++ ○Managed C++:UnManaged C++間の呼び出し時間が短い ○マルチランゲージによる開発の利点を享受できる ×???(未確定要素) ×???(意味不明) ×Managed C++:UnManaged C++間でクラスが使えるか? 3.VB6:メモリ:別プロセス ○???(意味不明) ×仕組みが複雑 ×呼び出しに時間がかかるのでは? まずは、どうして市販のデータベースを使わないのか、というところでしょうか。後々も使い回して行くことが予想されているようですが、それならば余計に、作り込むのではなく、市販のものを利用する方が安全だと思います。 どれくらいのものを考えなければならないのかわかりませんが、ネットワーク越しのアクセス、同時実行、障害発生時のデータの安全性等々、テストしなければならないケースだけで、予算をオーバーしませんか?それよりも、チューニングに注力する方が安くなると思います。また、安全性も保証されていますし、他に聞くことも出来ます。 データ量が2〜100GBということですが、一時にすべて必要とも思えませんし、SQL ServerやPostgreSQLであるなら、C++で内部関数を作ることも出来るようですし、処理内容をみて、ストアドプロシージャにさせるべきところはストアドプロシージャにさせ、インデックスを適切に張れば、そうそう問題になるとは思えません。 # あ、スペックが足りてないのかな? 次に、VB6とVC++.NETの組み合わせでしょうか。言及されているとおり、.NET Frameworkを使うと、CRLをネイティブに変換する処理が入ります。これは、実行が終わると破棄されるらしいので、インポートしたDLLがいつ破棄されるか不明ですが、少なくともVB6のアプリケーションを実行するごとに再翻訳の処理が入ることが予想されます。VC++6一本で作る方がいいと思いますが、いかが? それで、考えたこと1と2は、わざとVB.NETにしています。ここをどうつなげたいのか、わからなかったからです。ここがDllImportとかになるんじゃないかなぁ?2案の○2つめが、どうもVB.NETで同じソリューションにして、プロジェクトを参照すればそのまま使えるところのことをいっているのかなぁ?と思ったので、VB.NET+VC++.NET(Managed)と思っているのですが、なんか違うみたいだし。第一、出来ているアプリケーションはVB6だということだし。。。 他の言い方をすると、ここのつながりがわからないところで、私の思考は止まっています(^-^; で、ここで<良い点>としてあげられている、『マネージC++とアンマネージC++の関係が変わっても、MSが差異を吸収する仕組みを提供してくれる可能性』というのが不明です。関係って、どういう関係?VB6とVB.NETの関係のようなもの?しかし、移行ツールがあっても、このケースでは役に立たないのでは? また、『ボーランドやインテルのC++への私の乗り換え』というのも不明です。安全性を考えれば、バージョンアップは同一提供元で行うべきと考えます。“私”が使うツールを変えたからといって、業務(ですよね?)で作成するものを、変更するべきではないと思います。また、部や課として使用するツールが変わったとしても、すでに作成したものの保守は、それまでのツールで行うべきではないでしょうか。(いや、もちろん、ある時にすべて書き直すつもりで変更!ってのもアリで、このときの作業を少なくしたい、というのもあると思いますけど) VB6とVB.NETは、まったく違う言語(らしい)ので、その辺の情報ははっきりさせてください。 読んでもらえないと答えてもらえません。読ませる(「読んでもらう」ではなく、「読みたくなる」という意味で「読ませる」)にはどうすればいいか、そういうことも注意して、書かれることを勧めます。(人のこと言えないけど) _________________ |