C# と VB.NET の質問掲示板

わんくま同盟

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

ツリー一括表示

C++にC#を加えてひとつのexeに出来ますか /hojoR (23/09/06(Wed) 17:01) #102354
Re[1]: C++にC#を加えてひとつのexeに出来ますか /魔界の仮面弁士 (23/09/06(Wed) 17:28) #102355
  └ Re[2]: C++にC#を加えてひとつのexeに出来ますか /radian (23/09/06(Wed) 18:58) #102356
    └ Re[3]: C++にC#を加えてひとつのexeに出来ますか /とっちゃん (23/09/06(Wed) 21:15) #102357
      └ Re[4]: C++にC#を加えてひとつのexeに出来ますか /hojoR (23/09/07(Thu) 11:15) #102359
        ├ Re[5]: C++にC#を加えてひとつのexeに出来ますか /radian (23/09/07(Thu) 15:03) #102360
        └ Re[5]: C++にC#を加えてひとつのexeに出来ますか /とっちゃん (23/09/07(Thu) 15:46) #102361
          └ Re[6]: C++にC#を加えてひとつのexeに出来ますか /hojoR (23/09/08(Fri) 09:45) #102364 解決済み
            └ Re[7]: C++にC#を加えてひとつのexeに出来ますか /HattariB (23/09/08(Fri) 12:17) #102365 解決済み
              └ Re[8]: C++にC#を加えてひとつのexeに出来ますか /hojoR (23/09/08(Fri) 20:19) #102366
                └ Re[9]: C++にC#を加えてひとつのexeに出来ますか /hojoR (23/09/11(Mon) 16:01) #102368 解決済み
                  └ Re[10]: C++にC#を加えてひとつのexeに出来ますか /ななし (23/09/28(Thu) 11:44) #102436


親記事 / ▼[ 102355 ]
■102354 / 親階層)  C++にC#を加えてひとつのexeに出来ますか
□投稿者/ hojoR (1回)-(2023/09/06(Wed) 17:01:00)

分類:[.NET 全般] 

C++で作られた既存のexeがあるのですが、これにC#のコードを加え、ひとつのexeにすることは可能ですか?

・既存環境:VS 2010 MFC

・C#追加後の環境:上記のままでもよいしVS 2022も持ってます。

・C#ではFormなどのユーザインタフェースを追加したい。

・C++からC#スレッドを関数のように呼び出すイメージです。
 (マルチタスクはしません)

・ひとつのexeにしたい理由
 メモリに常駐させているデータをC++とC#で共有したいためです。
 共有データは、C++とC#どちらからも読み/書きし、サイズの変化(リストの要素増減)もあります。
 
よろしくお願いいたします。

 
[ □ Tree ] 返信 編集キー/

▲[ 102354 ] / ▼[ 102356 ]
■102355 / 1階層)  Re[1]: C++にC#を加えてひとつのexeに出来ますか
□投稿者/ 魔界の仮面弁士 (3689回)-(2023/09/06(Wed) 17:28:11)
No102354 (hojoR さん) に返信
> C++で作られた既存のexeがあるのですが、これにC#のコードを加え、ひとつのexeにすることは可能ですか?

無茶じゃないですかね。

やったことが無いので想像ですが、C++/CLI ではなく、MFC ということになると、
C# 製の DLL/EXE を COM 登録して呼び出すか、あるいは
github.com/3F/DllExport か www.nuget.org/packages/UnmanagedExports などで
関数ポインタを公開して呼び出すような実装になりますが…。
https://qiita.com/Midoliy/items/58d56e202f104ebf867a
https://qiita.com/s_Pure/items/95117fdf47ade5beb3de

さらにそれを「ひとつのexeにする」という要件まで入るとなると…。
ILMerge を使うこともできそうにないので、C# ライブラリを
MFC アプリのバイナリリソースとして埋め込んでおいて、
一時フォルダーに展開してから呼び出すとか、ですかね。
結局は別ファイルになっちゃいますが。


> ・C++からC#スレッドを関数のように呼び出すイメージです。
>  (マルチタスクはしません)
> ・ひとつのexeにしたい理由
>  メモリに常駐させているデータをC++とC#で共有したいためです。
>  共有データは、C++とC#どちらからも読み/書きし、サイズの変化(リストの要素増減)もあります。

それぞれ別の exe にしておいて、名前付き共有メモリや名前付きパイプ等を使って
プロセス間通信を行う…とかでは駄目なんですかね?
[ 親 102354 / □ Tree ] 返信 編集キー/

▲[ 102355 ] / ▼[ 102357 ]
■102356 / 2階層)  Re[2]: C++にC#を加えてひとつのexeに出来ますか
□投稿者/ radian (144回)-(2023/09/06(Wed) 18:58:02)
>・ひとつのexeにしたい理由
> メモリに常駐させているデータをC++とC#で共有したいためです。
> 共有データは、C++とC#どちらからも読み/書きし、サイズの変化(リストの要素増減)もあります。

データを共有したいだけなら、一つのEXEにする必要性はありません。
弁士さんの言うように、共有メモリや名前付きパイプを使うか、
データベースでも使ってください。
汎用性を考えるなら、データベースを使うのがいいと思いますが。

[ 親 102354 / □ Tree ] 返信 編集キー/

▲[ 102356 ] / ▼[ 102359 ]
■102357 / 3階層)  Re[3]: C++にC#を加えてひとつのexeに出来ますか
□投稿者/ とっちゃん (786回)-(2023/09/06(Wed) 21:15:42)
No102354 (hojoR さん) に返信
> C++で作られた既存のexeがあるのですが、これにC#のコードを加え、ひとつのexeにすることは可能ですか?
>
> ・既存環境:VS 2010 MFC
>
> ・C#ではFormなどのユーザインタフェースを追加したい。
>
<<カットしてる部分は後述>>

すでに魔界の仮面弁士さんが書いていますが
C++/CLI形式にする場合、exe/dll のどちらの場合でも VCランタイムはDLLリンクになります。
これは、C++/CLIのプログラム形式の仕様によるものなので回避策はありません。

また、MFCのランタイムもこの仕様の影響を受けるため、DLLでリンクする必要があります。
そのため、純粋な意味で1exeという形にすることはできません。


> ・C#追加後の環境:上記のままでもよいしVS 2022も持ってます。
>
VC++ランタイムをC++/CLIで利用する場合暗黙的な条件として
該当するVSがデフォルトサポートする、.NET Framework のバージョンを要求します。

VS2010の場合、4.0になるので、現実問題どこでおかしな状態になるかわからないという
潜在的不具合を抱えることになります。
要求バージョンを設定してもリンカーが利用するライブラリバージョンなどの都合で
うまくいかないことがあるので、VS2022に移行することをお勧めします。


> ・C++からC#スレッドを関数のように呼び出すイメージです。
>  (マルチタスクはしません)
>
C#のコードは別スレッドで動くということですか?
出来ますが、正直あまりお勧めしません。

ManagedスレッドとUnmanagedスレッド間でメモリのやり取りが必要な場合は
プロセス間通信と同じ方法でメモリのやり取りを行う必要があります。
Managedメモリは世代管理する関係で、物理メモリ上の場所を移動することがあります。
めったなことでは発生しないので、通常これが原因でエラーになることはありませんが
特定の条件がそろえば、移動することがあるのでそれが原因でエラーになることがあります。
.NET の仕様だし、.NET内に閉じている限りこれが理由でエラーになることはないので
通常は気にする必要もないことですが。

なので、ManagedスレッドとUnmanagedスレッド間でメモリをやり取りする場合は
プロセス間通信と同じ手法をとるか、Unmanagedメモリを利用してデータ転送する
必要があります(実質プロセス間通信に類似)。

> ・ひとつのexeにしたい理由
>  メモリに常駐させているデータをC++とC#で共有したいためです。
>  共有データは、C++とC#どちらからも読み/書きし、サイズの変化(リストの要素増減)もあります。
>  
メモリに常駐させているデータというのがどういうものかわかりませんが
Unmanagedのメモリは、C#から直接的には見れないので、Managedメモリに一度転送してから
参照することになります。

で、その多くの場合がほぼほぼプロセス間通信と同じ手法を用いることになるので
別スレッドで動かす前提なら、別プロセスにすることをお勧めします。


参考程度の情報ですが、過去に勉強会で、Formや、WPFのウィンドウを貼るという
セッションをやったことがあるのでリンクを貼っておきます。


・MFC(Doc/View形式)で、CView部分にFormsを貼り付けたい場合。

.NET Lab 2018/11 月の勉強会でしゃべっています。
https://dotnetlab.connpass.com/event/102490/
リンク先にセッション資料へのリンクもあります(動画はありません)。



・MFC の CView に WPFの画面を貼り付けたい場合。

わんくま勉強会東京#115でしゃべっています。
資料
https://1drv.ms/p/s!AuVVWpjfPyA0hPJZ3Dg8R0vFq6zt2w
ビデオ(2:40:00あたりから)
リンク張ると怒られるので、youtubeで「1/19わんくま同盟 東京勉強会」で検索してください。

サンプルプロジェクト
https://github.com/Tocchann/MfcOnWpf



[ 親 102354 / □ Tree ] 返信 編集キー/

▲[ 102357 ] / ▼[ 102360 ] ▼[ 102361 ]
■102359 / 4階層)  Re[4]: C++にC#を加えてひとつのexeに出来ますか
□投稿者/ hojoR (3回)-(2023/09/07(Thu) 11:15:29)
皆様どうもありがとうございます。

目的は、既存のC++データを共有しC#の便利な機能(主にユーザIF)を利用したいことであり、
「ひとつのexe」は必須条件ではありませんでした。

C++とC#をそれぞれ別の exe にする方向で進めてみます。


> C#のコードは別スレッドで動くということですか?

別スレッドではありません。
質問時に誤って「スレッド」と書いたので誤解を招いたかもしれません。
もうしわけありません。
言い直しますと、C#の処理をC++から関数のように呼び出す、ようなイメージです。
(C#の処理が終わるまでC++は待機する)


> メモリに常駐させているデータというのがどういうものか

CListを派生したいくつかの自前クラスが、親・子・孫・ひ孫…のように階層的に構成されています。
それぞれの自前クラスには、int・double・ポインタなどの単一変数や配列などが含まれます。
リストは、追加・削除・順序の入れ替えがされます。
表現が不適当かもしれませんが、Windowsのファイルシステムに似ています(階層的なフォルダ群に様々なものが入っている)。


> .NET Lab 2018/11 月の勉強会でしゃべっています。
> https://dotnetlab.connpass.com/event/102490/
> リンク先にセッション資料へのリンクもあります(動画はありません)。

拝見したところ「リンク先のセッション資料」が見つけられませんでした。
情報いただけると幸いです。
興味を持ったのは「Native アプリと .NET アプリを連動するいくつかの方法」です。

よろしくお願いいたします。

[ 親 102354 / □ Tree ] 返信 編集キー/

▲[ 102359 ] / 返信無し
■102360 / 5階層)  Re[5]: C++にC#を加えてひとつのexeに出来ますか
□投稿者/ radian (146回)-(2023/09/07(Thu) 15:03:48)
2023/09/07(Thu) 15:10:56 編集(投稿者)

No102359 (hojoR さん) に返信
> 言い直しますと、C#の処理をC++から関数のように呼び出す、ようなイメージです。
> (C#の処理が終わるまでC++は待機する)
>
>
>>メモリに常駐させているデータというのがどういうものか
>
> CListを派生したいくつかの自前クラスが、親・子・孫・ひ孫…のように階層的に構成されています。
> それぞれの自前クラスには、int・double・ポインタなどの単一変数や配列などが含まれます。
> リストは、追加・削除・順序の入れ替えがされます。
> 表現が不適当かもしれませんが、Windowsのファイルシステムに似ています(階層的なフォルダ群に様々なものが入っている)。

単純な値・構造体で表現できるようなデータ構造であれば、そのまま受け渡しできるのですが、
複雑なデータ構造なら、何らかの変換処理を挟む必要があると思います。

[ネイティブ相互運用性のベスト プラクティス]
https://learn.microsoft.com/ja-jp/dotnet/standard/native-interop/best-practices

データベースにぶち込んでしまえば、どの言語で使っているかというのを
あまり気にしなくてよくなります。
[ 親 102354 / □ Tree ] 返信 編集キー/

▲[ 102359 ] / ▼[ 102364 ]
■102361 / 5階層)  Re[5]: C++にC#を加えてひとつのexeに出来ますか
□投稿者/ とっちゃん (787回)-(2023/09/07(Thu) 15:46:32)
No102359 (hojoR さん) に返信

> 目的は、既存のC++データを共有しC#の便利な機能(主にユーザIF)を利用したいことであり、
> 「ひとつのexe」は必須条件ではありませんでした。
>
> C++とC#をそれぞれ別の exe にする方向で進めてみます。
>
exeはひとつで、中でいろいろ呼び出しと、ひとつのexeにして問うので方向性が違うので
誤解を招きやすいのかな?と思います。

MFCアプリで C++/CLI オプションを有効にした場合今までがどうであったかにかかわらず
以下のようになります。

C++/CLIのexe
MFCのDLLと、言語DLL
VC++のランタイム類(CRT)
C#のDLL
C#のDLLで参照される各種DLL(フレームワークに含まれないもの)

>
>>C#のコードは別スレッドで動くということですか?
>
> 別スレッドではありません。
> 質問時に誤って「スレッド」と書いたので誤解を招いたかもしれません。
> もうしわけありません。
> 言い直しますと、C#の処理をC++から関数のように呼び出す、ようなイメージです。
> (C#の処理が終わるまでC++は待機する)
>
通常のメソッド呼び出しで動かせればよいということですね。
其れであれば、Unmanaged(Native)<->Managedでのメモリやり取り(主に文字列や配列等)が
ある程度でそれほど難しくはないと思います(双方の知識は必要ですが)。

>
>>メモリに常駐させているデータというのがどういうものか
>
> CListを派生したいくつかの自前クラスが、親・子・孫・ひ孫…のように階層的に構成されています。
> それぞれの自前クラスには、int・double・ポインタなどの単一変数や配列などが含まれます。
> リストは、追加・削除・順序の入れ替えがされます。
> 表現が不適当かもしれませんが、Windowsのファイルシステムに似ています(階層的なフォルダ群に様々なものが入っている)。
>
CList(MFCのテンプレートクラス)を利用して階層的にデータ管理しているということですね。
自前のクラスも含め、直接C#では読めないので、C#でも読み書きできるデータ型を用意して(List<T>を使って定義するなどもあり)
C++/CLI部分でコンバートしてC#に渡すという形になります。


> 興味を持ったのは「Native アプリと .NET アプリを連動するいくつかの方法」です。
>
セッション資料へのリンクです。このリポジトリがそのままサンプルプロジェクトにもなっています。
https://github.com/Tocchann/dotnetlab1811/blob/master/Session.md

[ 親 102354 / □ Tree ] 返信 編集キー/

▲[ 102361 ] / ▼[ 102365 ]
■102364 / 6階層)  Re[6]: C++にC#を加えてひとつのexeに出来ますか
□投稿者/ hojoR (4回)-(2023/09/08(Fri) 09:45:38)
共有するデータ構造が複雑なので、未経験ですが「データベース」で検討してみます。

> https://github.com/Tocchann/dotnetlab1811/blob/master/Session.md

URL↑ありがとうございました。

そのほかにも皆様たくさんの情報を下さり、ありがとうございました。
理解が及ばないところもありますが、おいおい勉強してみます。

解決済み
[ 親 102354 / □ Tree ] 返信 編集キー/

▲[ 102364 ] / ▼[ 102366 ]
■102365 / 7階層)  Re[7]: C++にC#を加えてひとつのexeに出来ますか
□投稿者/ HattariB (79回)-(2023/09/08(Fri) 12:17:47)
No102364 (hojoR さん) に返信
> 共有するデータ構造が複雑なので、未経験ですが「データベース」で検討してみます。
ちょっと待って!
データベースは銀の弾丸じゃない。

もしもC++側で持ってるデータの構造がバランスドツリーみたいなもんだったら、
移植に苦労するよ。

「C#で追加したい事を、C++で実装する」と言う選択肢は残した方がいい。

解決済み
[ 親 102354 / □ Tree ] 返信 編集キー/

▲[ 102365 ] / ▼[ 102368 ]
■102366 / 8階層)  Re[8]: C++にC#を加えてひとつのexeに出来ますか
□投稿者/ hojoR (5回)-(2023/09/08(Fri) 20:19:02)
> もしもC++側で持ってるデータの構造がバランスドツリーみたいなもんだったら、
> 移植に苦労するよ。

バランスドツリーを初めて知りましたが、今回のデータはそれには該当しないようです。

今回のデータは下記のような形です。

CListA(CListの派生):最上層
CListB(CListの派生):2層目
CListC(CListの派生):3層目
 :
 :
リストの並びをソフトが自発的に変えることはなく、
ユーザの操作に応じて追加・削除・順序の入れ替えがされます。


> 「C#で追加したい事を、C++で実装する」と言う選択肢は残した方がいい。

コード追加をC#でやりたい理由は、
 ・表入力機能を実装したい(候補DataGridView)
 ・ユーザI/Fの開発効率がよい(実装したい機能が大抵、ツールボックスとプロパティの中で見つかる)

などですが、
C++で実装する選択肢も残しておこうと思います。

ありがとうございました。
[ 親 102354 / □ Tree ] 返信 編集キー/

▲[ 102366 ] / ▼[ 102436 ]
■102368 / 9階層)  Re[9]: C++にC#を加えてひとつのexeに出来ますか
□投稿者/ hojoR (6回)-(2023/09/11(Mon) 16:01:28)
「解決済み」が外れてしまったので付け直します。

解決済み
[ 親 102354 / □ Tree ] 返信 編集キー/

▲[ 102368 ] / 返信無し
■102436 / 10階層)  Re[10]: C++にC#を加えてひとつのexeに出来ますか
□投稿者/ ななし (1回)-(2023/09/28(Thu) 11:44:27)
既に解決済みになっていますが、C++とC#を一つのexeに格納する方法としては以下のようなライブラリを利用する方法があります

https://nekocha.hatenablog.com/entry/2022/12/24/102922

あまり深いことはやったことがないので詳しい解説はできませんが、参考までに
[ 親 102354 / □ Tree ] 返信 編集キー/


管理者用

- Child Tree -