-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
C#連携:C#側シリアライザの開発 #43
Comments
CMakeに上記のマージリクエストを投げてみました。 fix warning around 'Properties\Settings.settings' in Visual Studio この2件、マージされました。 |
C#の言語バージョンVisual Studio 2015は言語バージョン6、Visual Studio 2017は言語バージョン7です。 TheolizerはVisual Studio 2015以降に対応していますので、C#プロジェクトも同様とします。 C#の32/64bit32bitと64bit対応がややこしいです。 複雑な問題を避けるため、CMakeで32bitにて生成した時はデフォルトのAnyCPU、64bitにて生成した時はx64(64bit)でC#プロジェクトを生成することにしました。何か問題が発生したらその時再検討します。 C#とC++間のデータ交換シリアライズ済のデータを交換する部分にはC#側はStream、C++側はstd::istream, std::ostreamにて試作を進めています。 そこで、試作については下記の3本のストリームにてデータ交換する予定です。(試作中に変更する可能性もあります。)
2.と3.をマルチプレックスして1本にすることも恐らく可能ですが、多少オーバーヘッドが増えるのでまずは上記仕組みで進めます。 C++側のスレッド構成まずはC++はdllで試作を進めていますが、C#からの要求を受け取って処理するためのスレッドが必要です。(スタックフルなコルーチンでも可能ですが、当初はスレッドを使います。) イベント通知が必要になる場合(機器制御ではよく使います)は、main()関数処理でサブスレッドを起動してそちらに機器管理等のループを回し、そのスレッドが必要に応じてイベント通知を発行するイメージで考えています。 なお、main()関数スレッドで機器管理ループを回して、処理要求をサブ・スレッドで受け取ることも可能と思います。 非同期処理は今のところ考えていません。非同期処理関数を呼び出すためのスレッドをどうするのかの問題を考えるとサブ・スレッドを用いた同期処理がベストと考えています。 |
現状本日(2017/11/11)、csharp_integrationブランチへプッシュしました。 std::streambufに苦しみました。C#側はあっさりできましたが、性能をなるべく落とさないようにするため、殆どの処理をC++側で実装したこととstd::iostreamに苦労しました。メンバ関数の多さと直感的でない関数名が頭痛いです。そして、手を抜くとバイト単位でやり取りするのが頭痛いです。C++→C#側は複数バイト処理に対応しましたが、C#→C++側はまだ対応していません。どこかで時間をとってトライします。 連携クラスDllIntegratorを導入しましたこれがC#/C++の両方に存在し、C#とC++の接続を管理するクラスとなります。 ちょっとアイデアが浮かびました今は、C#がクライアント、C++がサーバで考えています。C#が要求を送りC++が応答を返します。 ところで、C++側はVisual C++に限定する必要は無いはずです。ネットワーク経由で連携できますから、IoT等のデバイスでC++11でプログラミング可能な機器なら理論上対応できる筈です。コンパイラがgccやclangなら現実的な期間で対応できるだろうと思います。 そして、IoT等への応用を考えるとC++をクライアントにしたいケースもありそうです。 更に、頑張ればC# dllをネイティブC++ exeから直接呼び出すなんて荒業も不可能ではなさそうです。 夢は広がるんですが、手が追いついていません。少しづつ進めていきます。 |
------ auto generated message by Theolizer TheolizerDriver : 2689a03ecf40efd14f058639020ad294 TheolizerLibrary : dee0663b4cbe3f7825471d270af1e67e Library's Header : be7336ad80b64315add4e50dfa3ebf05 ------ end of message
文字列や配列処理はまだ。 また、C++側はまだ単純なエコーバックなので、タイミングによってC#側がデータの終了判定に失敗する。 この問題はシリアライザで処理する時には発生しない。 ------ auto generated message by Theolizer TheolizerDriver : bbc4897a5dd0332296422621b3284e94 TheolizerLibrary : 7ad3c30327146d6d6f79a3708ba215f1 Library's Header : be7336ad80b64315add4e50dfa3ebf05 ------ end of message
33f0c65のコミットにて、C#側からの関数呼び出しのイメージを実装しました。その概念を説明します。 インテグレータ・クラス(DllIntegrator)これが接続を管理します。ストリームは3本用意します。それぞのストリーム毎にシリアライザを生成します。
私自身の経験上はマスター/スレーブ接続ではこの3本を使うと必要な通信をスムーズに行えました。現ターゲットではマスターはC#です。マスターがクライアント(お客様.exe)となり、スレーブ側はお客様にサービスを行う(サーバ.dll)という考え方になります。 通知用ストリームを逆方向に流したり、応答を返したりしたいケースもあると思います。 メンバ関数の呼び出しC++側でコーディングしたクラスの内、「C#連携」として保存先指定したメンバをメタ・シリアライザにてC#側クラス定義へ自動変換する予定ですが、その時のメンバ関数の動作モデルの一部を記述しています。 最終的な姿は、下記を想定しています。
上記の内、要求を投げるための関数クラスのオブジェクトを生成してJsonにてシリアライズしてC++へ投げるところまで実装しています。今後、C++側のデシリアライザで受け取り、応答を返却する部分までを第一ステップとして開発を進めます。 その後、Issue #42 の「4-2.C#側メタ・デシリアライザの開発」に着手します。 使用するインテグレータ・オブジェクトDLLモデルでは連携接続は1本で十分と思うので、シングルトンにしていますのでインテグレータ・オブジェクトは1つだけ有効です。 DllIntegratorはシングルトンなのでスレッド・ローカル・ストレージへ記録する必要はないのですが、上述した 1. 処理は自動生成するコードにて行います。この中で使用するインテグレータ(接続)を獲得し、そのシリアライザを取り出してそこへシリアライズします。このインテグレータの取り出しは DllIntegratorだけでなく、他のインテグレータでも使えるようにしたいため、スレッド・ローカル・ストレージ(staticクラスThreadIntegrator)を使用してみました。 別案としては、各メンバ関数呼出し時のパラメータでインテグレータを指定することが考えられます。ほとんど常に決まったパラメータを毎回指定するのは面倒ですし、バグの元なのでこの案は棄却しました。 |
------ auto generated message by Theolizer TheolizerDriver : 6c53ef20c964c17f46239caa662fb77a TheolizerLibrary : 2040eb742423f16db70cd2d7054ec745 Library's Header : d41d8cd98f00b204e9800998ecf8427e ------ end of message
C#側のシリアライザが一応動作しました。 基本はC++側で提供するオブジェクトのメンバ関数をC#側から呼べるようにしたというものになります。実際のデータ交換はシリアライザを用いるためコピー・ベースとなりますが、必要な情報を全てコピーするため、アドレスを除けばオブジェクトを転送できていることになります。 現在のテスト実装内容
残務
今後の予定少し別件で忙しくなりそうなので時間がかかりますが、上記残務を順次進めていきます。 |
関数クラスの回復処理実装前 C#側のインテグレータを共通部(core_integrator)とカスタム部(integrator_dll)へ分離 ------ auto generated message by Theolizer TheolizerDriver : 3212bd352466f7713ae15e990795c2c6 TheolizerLibrary : 7772ee1a2415186b0d3674930ee43da8 Library's Header : d41d8cd98f00b204e9800998ecf8427e ------ end of message
詳細は→#43 (comment) ------ auto generated message by Theolizer TheolizerDriver : 48d07d3ad3551d725ca23930a68a4cba TheolizerLibrary : 716c9d95044e8e4ab1422cff4d6a2d24 Library's Header : d41d8cd98f00b204e9800998ecf8427e ------ end of message
linux側Sharedライブラリ版で.soなしエラー発生し、対策した LD_LIBRARY_PATHの修正 ------ auto generated message by Theolizer TheolizerDriver : 4ce275cf7be1c5029d748e6b37afe48a TheolizerLibrary : 35a023364efdd5b356bc4a78269b1d06 Library's Header : d41d8cd98f00b204e9800998ecf8427e ------ end of message
現在、共有オブジェクトの仕組みを試作しています。 C#のように参照があれば開放されない方式とします。 「C++からC#への通知」を実装しつつ上記の仕組みを試作しています。この「通知」の仕組みが出来上がったら、細かい部分を整えた後、メタ・シリアライザ開発に着手します。 |
これにより、issue #43 の試作はほぼ完了。 他の環境でのビルド等の細かい調整を行った後、メタ・シリアライズを着手する。 ------ auto generated message by Theolizer TheolizerDriver : 8fbef0ef7df37d6f366d6cd196904e3d TheolizerLibrary : 58c82a663903f4a46cfe5dba517cb1e4 Library's Header : d41d8cd98f00b204e9800998ecf8427e ------ end of message
linux用にfPIC_ON設定追加 これがTRUEの時、 TheolizerLib/Testのコンパイル・オプション-fPICを追加する。 リンクするboostをfPIC版に切り替える。 なお、reference_and_testは最小限のテストへシュリンクしている。 ------ auto generated message by Theolizer TheolizerDriver : 9497aad84d549596f73340bfe5a6876c TheolizerLibrary : 5cdcd195b3db63abe09079b819156a49 Library's Header : d41d8cd98f00b204e9800998ecf8427e ------ end of message
------ auto generated message by Theolizer TheolizerDriver : 9497aad84d549596f73340bfe5a6876c TheolizerLibrary : 5cdcd195b3db63abe09079b819156a49 Library's Header : d41d8cd98f00b204e9800998ecf8427e ------ end of message
共有オブジェクトの仕組みの試作完了し、C++側についてMinGWとgccでビルドできるようになりました。 ただし、MinGWによるDLLをC#から呼び出すことには成功していません。 以上によりライブラリ・レベルでの技術的課題をほぼクリアできたと思いますので、メタ・シリアライザ開発を着手します。 下記残務については、メタ・シリアライザ開発と前後して対応します。
|
この作業も少しステップを踏みます。
1.C#プロジェクトをCMakeで生成する
そもそもC#側をGUI対応にしたいので、Windows Formsとして生成中です。
概ねできたのですが、CMakeの不具合が2つ見つかっています。
CMake で C# のプロジェクトを作ろうとしてハマった話はこれです。
CMakeのGitLabにマージリクエストを投げる予定ですが、上記発見者の了解を貰おうと待っているところです。しばらく待って回答を貰えない場合は、必要なリンクを貼ってから投げようと思います。
もう一つは、正直ほっといても良いと思うのですが、Settings.Designer.csをC#プロジェクト・ファイルに仕込む時にミスがあるようで、Visual Studioが警告してきます。警告通り処理するとSettings1.Designer.csができてしまい、ちょっと気持ち悪い状況です。
CMakeのソースをcloneしていたので、ちょっと覗いてみると意外に簡単に修正できそうなので修正してみたところ、少なくとも上記トライしているプロジェクトでは警告がなくなりました。
マージリクエストしようかどうか考え中です。CTestするとFailするので悩ましい状況です。
2.ストリームにてデータ交換できるようにする
C#とC++間のデータ交換はシリアライズされたバイト列で行います。それをC#側クライアントexeとC++側サーバdllにてやり取りしたいため、その仕組みを実装する予定です。
C#側はStreamを派生、C++側はstdd::streambufを派生して出来るはずですので、チャレンジしてみます。
3.そしてC#側のシリアライザ開発に着手します
最初はデバッグしやすいようJson形式で考えています。
その後Binary形式の開発になりますが、こちらはもしかするとクラウドソーシングで外注するかもしれません。恐らく年内は厳しいと思います。
The text was updated successfully, but these errors were encountered: