MFCからC#への移植スピード

[戻る]
Moo 2014/08/04(月) 20:54:41
いつもお世話になってます。

以下の2つの作業についてどちらが効率が良いと思いますか?
個人差があると思いますが、ご意見頂けると助かります。

1.MFCのソースコードがあり、そのGUI部をC#にするためコアとなるクラスをDLL化する。
  DLL化する際にMFCのAPIをWin32APIに置き換える必要があり、エラー量は3000〜5000
個。
  エラーの理由はCString,CFindFile,CTime,クリティカルセクションなどを使っている
事や
  マルチバイト文字をUNICODEに変換する必要があるため。

2.上記を1からC#で作りなおす


以上、宜しくお願い致します。

tetrapod 2014/08/05(火) 06:24:24
GUI 画面を作るための部品ってのは C# のほうが充実している。
その既存の GUI ってのが MFC の CWnd 派生部品の切り貼りでできてる程度なら
> 2.上記を1からC#で作りなおす
のほうが圧倒的に簡単だと思う。

> DLL化する際にMFCのAPIをWin32APIに置き換える必要があり
って MFC->.NET 化の際に .NET Framework の部品を使わずにやろう、ってこと?
C# で作るのなら Win32API の出番などまず無い(特殊な用途を除く)ので
その意味でも「全捨て、作り直し」に1票。

プログラマが C# そのものをどの程度理解しているか、使えるか、でも違うけど
その辺はどうなのかな?

参照型と値型の違いとか
System.String はかなり特殊な参照型であるとか
IDispose の正しい使い方とか
その辺が理解できていれば
「そもそもバグっているコードが記述できない」よう作ってあるのが C# だし
.NET Framework の標準部品の数も質も充実しているし、
こと「Windows での GUI 画面作成」の1点だけ取れば C# 一択だと思う。

# ほかの人の意見も訊いてみるといい。

Moo 2014/08/05(火) 09:34:59
早速のご連絡有難うございます。
非常に参考になります。

tetrapod の記述に追記させて頂きます。

>って MFC->.NET 化の際に .NET Framework の部品を使わずにやろう、ってこと?

はい、MFC->Win32APIを用いたソースをDLL化して、C#へエクスポートしようと考えてまし
た。(この方法なら実現可能ですよね?)


>プログラマが C# そのものをどの程度理解しているか、使えるか、でも違うけど
>その辺はどうなのかな?

この辺はC++は10年経験ありますが、C#ははじめてです。
C++のバグ修正よりC#学習の方が時間はかかりますが、スキルアップに繋がりるかと思って
ます。

他の方のご意見も頂けると幸いです。

仲澤@失業者 2014/08/05(火) 10:45:41
1.一般にコードの部分をDLL化するためだけに、MFCをWin32APIに置き換える必要はない
はず。

なのですが、まぁそれは置いといて、

2.標準的なコントロールを使っている程度の画面であればC#の方が早いです。
 もちろん、ある程度熟練していればであって、C#初心者では難しいかもしれません。

3.C++に熟練していることと、オブジェクト指向に熟練していることは、
 あまり比例しないという場面に良く出会います。

後者の理解が深いと、C#もJavaも慣れるのはわりと簡単だという
印象があります。

C#では、普通のアプリがわりと簡単に作れるのですが、
あまり工夫の余地がないので、ちょっと凝ったことをしようと思うと
結局Win32APIだらけってことになります。

まぁ両方やってみてはどうでしょう。

AR 2014/08/05(火) 11:00:06
 まず想定されているように、かなり属人的な回答になると思います。

 私も「DLL化する際にMFCのAPIをWin32APIに置き換える必要があり」という理由がイマ
イチピンときてません。
 以前の会話の流れから、DLL内でMFCを使えないと思われてるのかなぁ?と思っています。
 エクスポートをCのインターフェイスにするだけですし。

 一応、DLL内でMFC使うヒント書いておきます。
ヘッダファイルの記述
#ifdef __cplusplus
extern "C"
#endif
{
 int WINAPI DllFunction(void* pTekitoParam);
}

CPPファイルの記述
int WINAPI DllFunction(void* pTekitoParam)
{
 CString strPath;
 //MFCを使うにはライブラリをincludeする必要がある
 //雛形は新規作成→プロジェクト→MFC DLLでスケルトン作って比較すると良い
 /*何らかの処理*/
 return 1;
}

defファイル
EXPORTS
  DllFunction  @1

 これらが勘違いで、本当にMFC→Win32APIに変える必要があるのならば、作り直したほう
が早そうだなと思います。


 実務だと、ライブラリへの依存度が高くなりがちなフレームワーク系のコードと、あま
りライブラリに依存しないビジネスロジックの割合で考えることが多いです。
 あとはエンジニアの確保のしやすさとか、単金、確保できる工数などが、結構大きなウ
エイトを占めますので、その時々で選択は変わってきます。
 ですから、単純にエラー量程度で判断すべきではない(提供情報が少なすぎ)という意
見です。

 ただ勉強目的という要素を入れるなら、C#一択です。
 技術の幅が広がりますし、凡バグを作りこめず簡潔な記述が可能な世界と、そのデメ
リットを垣間見るのは良いことだと思います。

Moo 2014/08/05(火) 11:10:57
tetrapod様
申し訳ございません。先ほどの記述で呼び捨てにしてしまいました。

Moo 2014/08/05(火) 11:15:22
仲澤@失業者様、AR様
ご連絡ありがとうございます。非常に助かります。


私の方で検討漏れがあったようで・・。

そもそも
[新規作成→プロジェクト→MFC DLL]のDLLは
C#でも使えるのですか?使えないと思い
もし可能でしたら、今までの悩みが一気に解消します!

備考:今までObject-C、Java(Eclipse)などを扱った事もあります。

また、C#のWPFに非常に魅力を感じているので
出来れば

GUI⇒WPF(C")
既存ライブラリ(MFC依存のlib)⇒DLL(簡単な移植)

で進めたいです。

Moo 2014/08/05(火) 14:32:00
MFCをC#で動作させる方法について
ひとまず、以下の方法で実現ができました。

http://code.msdn.microsoft.com/windowsapps/VisualC-howto-76f9cd9e

この方法はスタンダードと解釈して宜しいでしょうか?

AR 2014/08/05(火) 16:38:09
 前提をひっくり返すようで恐縮ですが、質問の内容が「効率」→「スタンダード」に変
わってるので回答も変わります。

 スタンダードか?と言われれば、C#からCLI交じりのMFCのDLLを呼び出しする行為自体
がイレギュラーだと個人的には思います。
 例えばライブラリをObjective-Cで、UIをJavaでとコードを混ぜるのはどう思います?
と言えば雰囲気が伝わるかもしれません。

 ↑で私が書いた、MFCを用いたコードをC形式でエクスポートするのはWin32APIの呼び出
しと同じなので良くあるコードと言えます。
 仕組みを理解されていないようなので、ダイナミックリンク(動的リンク)と、スタ
ティックリンク(静的リンク)この二つの違いをキーワードに勉強してみてください。


 標準的な技術の採用と言うことならメンテナンス性も考えて、CLI+MFCという構成は私
なら採用しません。
 既存資産を生かすとか、絶対的なパフォーマンスが必要という目的ならば、採用します。
 XMLの時のスタンダードか?も気になりましたが、目的があってそれに適した手段を選
ぶものであって、手段を先に選ぶのは本末転倒だと思います。
 例えばXMLのライブラリだって、世の中にはたくさんで回っており、それぞれメリッ
ト・デメリットがあるわけですからね。

Moo 2014/08/05(火) 17:16:10
AR様
ご連絡有難うございます。

MFC DLLに関しては先ほど書いて頂いたコードを元に以下のサイトなど
色々と参考にしてみたのですが、未だうまく実装できてません。。

http://d.hatena.ne.jp/twhs/20080216/1203189125

現状、苦しまぎれに何とかCLIで実装出来た段階です。

1点確認させてください。
1つ前のコメントは以下の解釈で合ってますか?

---------------------------------------

(1)CLIでは「共有 DLL で MFC を使う」の設定の為
 ⇒スタティックリンク(静的リンク)

(2)MFC DLLでは「スタティックライブラリでMFCを使用する」の設定の為
 ⇒ダイナミックリンク(動的リンク)

---------------------------------------

もし合っているのでしたら、(2)の方が汎用性は高く感じられます。
しかし、CLIも成果物はDLLなのでMicroSoftのランタイムライブラリに依存する以外は
(2)と変わらない気もします。

Moo 2014/08/05(火) 17:21:40
AR様
追記させて頂きます。

>標準的な技術の採用と言うことならメンテナンス性も考えて、CLI+MFCという構成は私
なら採用しません。
> 既存資産を生かすとか、絶対的なパフォーマンスが必要という目的ならば、採用しま
す。
> XMLの時のスタンダードか?も気になりましたが、目的があってそれに適した手段を>ぶものであって、手段を先に選ぶのは本末転倒だと思います。
> 例えばXMLのライブラリだって、世の中にはたくさんで回っており、それぞれメリッ
>ト・デメリットがあるわけですからね。

先々までの見解を頂き感謝致します。
仰る通り、工数と要件定義が本末転倒の原因となっているのが正直な意見です。
(XMLの時もどうすれば出来るか!?から調べているもので、、一般的な意見を伺いたかっ
た次第です。)

今回、限られた時間で膨大な既存資産(VC++)と新規GUIの組み合わせが必要ですので
それに見合った検討を引き続きしていきたく思います。

皆様のアドバイス、非常に感謝しております。
引き続き、宜しくお願い致します。

AR 2014/08/05(火) 18:24:56
>1つ前のコメントは以下の解釈で合ってますか?

 話がそれるので、細かい所は割愛します。

 DLLのMFCのプロパティの値の話ではありません。
 上位アプリケーションから、DLLを呼び出すカラクリの話をしています。

 静的リンクするEXEは、DLLが無いと起動すらしません。
 動的リンクするEXEは、DLLがなくても起動します。

 後者は完全にアプリケーションと、DLLを分離させ独立させることができる構成になり
ます。
 例えば統合アーカイバプロジェクトDLLを使ってるソフトで、DLLが全部揃ってないと起
動しないと言うことはないですよね。
 このようにメリットとしてモジュール結合度を下げることができるため、良く使われる
手法になっていいます。
 デメリットはLoadlLbrary()やGetProcAddress()などで、DLLそのものを読み込む部分か
ら自分で作らなければなりません。

 細かく語ると相当長くなるし、詳しく説明されているサイトも多々あるので前述のAPI
の使い方辺りを参照ください。



>今回、限られた時間で膨大な既存資産(VC++)と新規GUIの組み合わせが必要ですので
>それに見合った検討を引き続きしていきたく思います。

 であればCLI+MFCというのも「個人的に」スタンダードとは思わないけど有りだと思い
ますよ。

tetrapod 2014/08/05(火) 18:28:01
> 膨大な既存資産(VC++)
をそのまま無変更で使うことが優先ならば C# (.NET) を諦めて MFC を使い続ける

既存の C++ 資源を C++/CLI に移植する=つまるところ書き直しぢゃん
=再度デバッグが必要、というのは限りなく無駄っぽい気がする。

.NET 系の [マネージ] の世界と
C/C++ の [アンマネージ] の世界の間には壁があるので、
C# をこれから勉強しよう (かつ時間も限られている) というレベルならば
マーシャラなどというニッチ分野をほげほげしている時間がもったいないと思う。
移行しないほうが無難だろう。

>CLI+MFCという構成は私なら採用しません。
同感。
・既存コードを捨て、完全に .NET の世界向けに0から書き直す
・既存コードを活用するため現状の開発体制を維持する
どっちかだ。

既存 native コードを .NET 界から使えるようにするってのはハードルが高い。
native 側が歩み寄るにせよ .NET 側が歩み寄るにせよ。

# 俺も VC++ 用に書いた DLL を C# から使ってみた経験あるけど
# 最終的には VC++ 全捨てして C# だけで書き直ししてしまったよ

Moo 2014/08/05(火) 18:59:25
[[解決]]
AR様
アドバイス有難うございます。

なるほど、元々のコンセプトは
「DLL化した資産を様々なEXEで流用したい」事から始まってます。
それが、既存コードのMFC依存、C++とC#の互換性などで検討点が多くなり
このような事態となってしまいました。。。

しかし、ここまでご教授頂ければ一人で何とか調査できそうです。

未だ幾日か余裕がありますので
CLI+MFCは非常に移植が楽で使いやすいので、
引き続き動作保障できるか調査してみます。

------------------------------------------

tetrapod 様
「1」か「0」とはっきり言って頂いて正直すっきりしました。
ゼロからC#で移植されたのですね、、、大変さが目に浮かびます。。

確かにCLI+MFCでも結局デバッグが必要ですから
今回の対策は暫定策として考え
水面下で共通して使えるプラットフォームの確立を進めていこうと思います。

皆様、本当にありがとうございました。

これで解決とさせて頂きます。

古いスレッドには追加発言できません。