NPの作成と留守番ロボット接続

現在、NPのモジュールの作成と、留守番ロボットを接続する作業を行っています。


まず、NPのモジュール。
こいつは、一旦、クライアントモジュールの整理から行いました。というのは、NPのモジュールとクライアントのモジュールで共通化できそうな部分を、クラスライブラリとしてぶっこ抜く作業です。
次に、NPのモジュールの作成。
こいつは、単体のコンソールアプリにしました。まぁ一種のクライアントソフトですね。
サーバー側に組み込んでしまおうかとも思ったのですが、CPUパワーとディスクパワーが不安だったので、別のEXEにしてしまいました。
NPモジュールからのサーバーへの接続や、イベントハンドラ関係は、先に準備したクラスライブラリで、さくっと修了。
現在、留守番ロボットをこのNPモジュールにつなぐ作業を行っています。
実は、以前、3時のおやつというチャットで活躍していた、この「留守番ロボット」。C#で書かれています。一部ManagedC++を使っていますが、ほぼC#で書かれています。
今回、このNPモジュールはC++で書いています。
ここで問題、C++からC#のクラスをどのようにして叩くか。
またもや師匠に教えを頂いてしまいました。
概念をさっくり説明してもらいました。なるほど、とりあえず可能なわけね。というか考えてからはじめろって話もあるが。。。
アンマネージ コードとの相互運用
やら
COM 相互運用性 – 第 2 部 : C# サーバー チュートリアル
が、ポイントらしい。ということで、オンラインで読書。早速お試し。
「regasm.exe」を使うと、C#のDLLをCOMとして登録&tlbの生成&regファイルの生成 ができるらしい。
そこで、「regasm.exe」を実行してtlbを生成、tlbを、C++のソースの中で#importしてコンパイル。Debugフォルダの中に、スタブのコードが生成されるので、ちょっと失礼して観察。
インターフェースはできてるけど、インターフェースの中身が入って無いじゃん。
COM 相互運用性 – 第 2 部 : C# サーバー チュートリアルをよくよく見ると、インターフェースをちゃんと定義しないと駄目みたい。
横着して既存のクラスをコピペしてインターフェースを作る。んで、試すと、、、
いろんなクラスがメソッドの引数として使われているので、IUnknown*がいっぱい飛び交う。
こりゃいかん。ラッパを書かなくては。
ということで、C#でちょっと便利なラッパクラスを書く。
今は、イベントに伴って動作をしていくクラスだったので、クラスの使い方の上下関係もちょいちょいと入れ替えて、C++側から呼び出して使えるように変更。
無駄なインターフェースもさっくり整理。
んで、試すとちゃんとインターフェースが生成された。
さて、次は、CoCreate。
コンパイルとおらへん。というのは、CLSID_なんちゃらがあらへん。
どないなってんねん。考えてみれば、#importではスマートポインタ用のヘッダが出てくるから、書き方がちょっと違うのだ。CComQIPtrでいつものように書こうとした俺があほやった。
COM 相互運用機能のサンプル : COM クライアントと .NET サーバー
ILoanPtr pILoan(__uuidof(Loan));
の行を参考に、ちょいちょいと修正。
まだコンパイル通らん。
もう一度生成されたコードを見直すと、、、、あらら、ちゃんとnamespaceまで生成されてるのね。ということで、namespaceにあわせて修正。
コンパイルは通るようになった。
毎度のことながら、CoInitializeが呼ばれてませんと怒られる。
次は、クラスが登録されていません。
おぃおぃ。ちゃんとDLL登録したじゃん。
調べてみると、C#のDLLはSide-by-Side。考えてみれば当たり前だ。
DLLをコピー。
CoCreate成功。
次はメソッドの呼び出し。
何故か例外を投げられる。
なんでぇ?
ちゃんとできてないのかな。が、ちゃんとポインタは入っている。ステップインできないところがムカつく。
C#側が悪いのかなと、C#側に空のメソッドを作って呼び出してみると、ちゃんと呼び出せる。
ありり?相互運用の問題じゃないらしい。
調べてみると、DBの接続の部分に問題があり。接続文字列作るの忘れてた。
ということで、C#のクラスをC++側から呼び出すことに成功。
さ、こっから一気に留守番ロボットを復旧するぞ。
コンソールアプリでタイマーってどうやって実装しようかなぁ。。。。

コメントを残す