質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
VB

VB(ビジュアルベーシック)はマイクロソフトによってつくられたオブジェクト指向プログラミング言語のひとつで、同社のQuickBASICが拡張されたものです。VB6の進化版といわれています。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

1回答

1903閲覧

VBをC#に翻訳して出たInteraction/RuntimeHelper/NewLateBinding/Conversionをなくしたい

TrainRain

総合スコア20

VB

VB(ビジュアルベーシック)はマイクロソフトによってつくられたオブジェクト指向プログラミング言語のひとつで、同社のQuickBASICが拡張されたものです。VB6の進化版といわれています。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

0グッド

1クリップ

投稿2018/12/10 05:20

編集2018/12/10 07:06

こんにちは。

前提・実現したいこと

Windows10を使ってVisual Studo 2017でWindowsFormアプリケーションのプロジェクトを作っています。
もともとVisual BasicのプロジェクトだったコードをC#に書き換えています。
Visual Basicを書いた担当はいないので、詳細は不明です。
Visual Basicのコードは動作しています。
ILSpyでコンバートしたC#のコードも動作しています。

それぞれのコードは下記のとおりです。

発生している問題

もともとのVisual Basicのコードに比べて複雑で、わかりにくいです。
usingでMicrosoft.VisualBasic.CompilerServices;を使っていて、それもなくしたいです。

4点ほどわからない点があり、質問しました。
(1)Interaction.CreateObjectとはなにで、C#で処理する方法は?
(2)RuntimeHelpers.GetObjectValueとはなにで、C#で処理する方法は?
(3)NewLateBinding.LateGetとはなにで、C#で処理する方法は?
(4)Conversion.ChangeTypeとはcastと違うのか?
以上です。

当方、Visual Basicはぜんぜん読めません。
アドバイスいただければ幸いです。

該当のソースコード

C#

1using Microsoft.VisualBasic.CompilerServices; 2using System.Runtime.CompilerServices; 3 4namespace FeliCaAccess 5{ 6 public class FeliCaObjectModel 7 { 8 public int SetupResult; 9 public objuct Ifd; 10 public objuct IcCard; 11 public objuct FeliCa; 12 13 object[] objects = new object[1] 14 { 15 IcCard 16 }; 17 bool[] CanWrite = new bool[1] 18 { 19 true 20 }; 21 22 public FeliCaObjectModel() 23 { 24 Ifd = RuntimeHelpers.GetObjectValue(Interaction.CreateObject("IFD.RW", "")); 25 IcCard = RuntimeHelpers.GetObjectValue(Interaction.CreateObject("ICC.Card", "")); 26 FeliCa = RuntimeHelpers.GetObjectValue(Interaction.CreateObject("FeliCa2.API", "")); 27 28 objects = new object[1] 29 { 30 IcCard 31 }; 32 33 object returnValue = NewLateBinding.LateGet(FeliCa, null, "SetUp", objects, null, null, CanWrite); 34 IcCard = RuntimeHelpers.GetObjectValue(objects[0]); 35 SetupResult = Conversions.ToInteger(returnValue); 36 } 37 } 38}

VisualBasic

1 Public ifd As Object '// IFDオブジェクト 2 Public icc As Object '// Cardオブジェクト 3 Public fel As Object '// FeliCaオブジェクト 4 5 ifd = CreateObject("IFD.RW") 6 icc = CreateObject("ICC.Card") 7 fel = CreateObject("FeliCa2.API") 8 9 result = fel.SetUp(icc)

補足情報(FW/ツールのバージョンなど)

Intel Pentium(R) CPU 4415 Y 1.60GHz RAM 8GB Windows10Pro 64bit 1803 17134.345 Microsoft Visual Studio Community 2017 Version 15.8.5 VisualStudio.15.Release/15.8.5+28010.2036 Microsoft .NET Framework Version 4.7.03056 インストールされているバージョン:Community

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kenshirou

2018/12/10 05:56

元のVBのコードは、「Public ifd As Object」以下に書かれているものでしょうか?それをC#に置き換えたものが「C#」と書かれた内容なのでしょうか?(別物に見えたので質問しました。)
TrainRain

2018/12/10 07:07

はい。そうです。わたしにもほとんど別物に見えます。変数名をC#っぽくした以外は、機械翻訳の結果で、いじってません。
guest

回答1

0

(1)Interaction.CreateObject
(2)RuntimeHelpers.GetObjectValue
(3)NewLateBinding.LateGet
(4)Conversion.ChangeType

については、検索すると詳細な説明がありますが、C#で今回のようなことを実現しようとすると、色々と面倒なことをやらなければならないようです。

VBでCOMオブジェクトを使用する場合、簡単に言えば、COM参照をしなくとも、遅延バインディングという方法でCOMオブジェクトを使用することができます。
それが、VBのCreateObject(xxxxx)という構文です。
有名なところが、 CreateObject("Excel.Application")のような、MS Office製品操作でしょうか。
遅延バインディングの利点は、そこで使用するソフト(上記例ではExcel)のバージョンを問わないことです。
例えば、Excel2016が入っているPCで開発したアプリをExcel2013が入っているPCで動かすことも可能です。
(前提として、Excel2016とExcel2013で同じ動作をする共通メンバを使用することが必要です。)
ただし、遅延バインディングの欠点として、オブジェクトの型が明示されない点です。
当然、オブジェクトの公開メンバの状況も分からないことになります。
VBで遅延バインディングを使用すると、例えば以下のCOMオブジェクト変数

fel = CreateObject("FeliCa2.API")

にSetUpという公開メンバがあるかどうかわからない状況でも、

fel.SetUp()

という構文を書くことが出来、実行時にその公開メンバの評価がなされます。

それに対して、C#では、このようなことは出来ず、

fel.SetUp();

のような構文を書く場合、felという変数の元クラスが特定でき、そのクラスにSetUpというメンバが存在することが特定されないと文法エラーになってしまいます。
(VBでも、Option StrictをOnに設定すると同様のことになります。)

VB側では楽に遅延バインディングを行えるのですが、C#で遅延バインディングを行う場合には言語的な厳密さが必要となり、色々と手間なようです。

投稿2018/12/10 07:27

編集2018/12/10 07:49
kenshirou

総合スコア772

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

TrainRain

2018/12/10 08:38

なるほど。丁寧な説明ありがとうございます。 わたしはC#しか使ったことがないので、Visual Basic風に遅延バインディングする必要はなく、C#的にCOM参照して使えればよいです。 実際、このプロジェクトは動いているので、COM参照済みと思います。 その場合で、どう書くとC#的なコードになるのでしょう…。
kenshirou

2018/12/10 09:08

提示頂いたC#のコードを見ると、Interaction.CreateObject("IFD.RW", "")のように書かれていますので、これらは遅延バインディングとなります。 遅延バインディングを使用しない場合はCOM参照を行えばよいのですが、残念ながら、"IFD.RW", "ICC.Card", "FeliCa2.API"で表されるものを扱ったことがないので、これらのCOM参照は識者にお任せします。 お役に立てず、ゴメンナサイ。
kenshirou

2018/12/11 01:07 編集

ところで、"IFD.RW" "ICC.Card" "FeliCa2.API"でググると、以下がヒットしました。 FeliCaチップへの 秘密分散共有法の適用 - 神奈川大学 http://kinoshita.ee.kanagawa-u.ac.jp/2008/sasaki/sotsuron-full.pdf (他にヒットしたのは、この投稿のみでした...) この論文は10年前のもので、使われているFelicaのAPIはそれ以前には既に存在したものだと思います。 "IFD.RW", "ICC.Card", "FeliCa2.API"の提供元に確認するのが一番ですので、確認してみてください。 (そもそも現在もサポートしているかどうか不明です。) それが難しいようであれば、現在の方法に甘んじるより他ないかも知れません。
TrainRain

2018/12/11 06:04

ご推察のとおり、これはFeliCaのシステムです。 この論文のD社のVisual Basicのコードを、C#に変換したものです。 提供元にはもちろん最初に確認しました。 しかし、いろいろな大人の事情で回答をもらえないのです。組織とか予算とか担当とか、そういう問題です。手元に資料がなく、探すに担当がおらず、情報提供には組織の複雑な壁があるとかです。
YAmaGNZ

2018/12/11 06:10

そういう事情なのであれば、COM参照に変えて何かあってもサポートして貰えないということなのではないのですか? それなら、「変えない」という選択肢が一番無難だと思いますが、変えなければならない事情があるのでしょうか?
TrainRain

2018/12/11 06:30

いちばんのモチベーションは、VBがわからない、ということに尽きます。 Conversion.ChangeTypeとはcastと違うのか? など、通常C#で書いていたら(VisualBasic名前空間なので)ぜったいに出てこないコードが入っています。 コード中にブラックボックスがあるのは嫌だな…、ということです。 あるいは、システムを置き換えるタイミングなので、「変えるなら今」ということもあります。 ただおっしゃるとおり、変えないことも選択肢ですし、個人的には残念ながらわからなかったので、今回は変えないことになりました。
kenshirou

2018/12/11 07:55 編集

COMの遅延バインドは、.Net前のVBやVBA・VBScriptで利用されていた技法のため、.NetのVBにも互換として残した、というように思います。 恐らく、.Net化の際、C#でも遅延バインディングを使えるよう移植したら、面倒なことをする必要性が出てきた、というのが本当の所ではないかと思います。 C#の言語の厳密さのため、VBと同じことをしようとすると色々と面倒、というのはある意味仕方ないのかと思いますので、とりあえず現状のC#のコードを使用する、というのが正解のように思います。 ただし、VBであっても、昔は意識しなくてよかったCOM解放を.Netでは明示的にしないといけない、みたいなことがあり、いずれの言語にしてもCOMの遅延バインドは色々と面倒です。
TrainRain

2018/12/11 08:28

誤解されている気がしますが、わたしは遅延バインディングしたくないです。 インテリセンスもきかなそうだし。 コンバートしたコードが勝手に遅延バインディングになっているだけで、それを撲滅したいのです。 COM参照で済むのならCOM参照でいいじゃないかと思ってます。 過去のコードに拘束されたくないのです。
YAmaGNZ

2018/12/11 08:42

そうなってくると、COM参照して書いてみればいいじゃないですかとしか言いようが無くなってくる気がします。 ご質問のものはILSpyが生成したC#のコードにあるもので、VB側のコードにはないわけですよね。 ILSpyが生成したC#コードをよりC#らしく変更するのもいいですが、COM参照してVBのコードをC#にするほうがスッキリ移植できるのではないかと思います。 VBが読めないと言われますが、細かい違いはあるでしょうが、そこまで大きくは違わないはずです。
TrainRain

2018/12/11 09:02

そうですねー。COM参照したいのはやまやまなのですが、どのCOMを参照したらよいかとかがわからないのです。論文でもありましたがdllは複数あり、COM参照して動くコードにするとか、マニュアルなしで手探りでは、無理と。 この件に関しては、タイムアップしてしまいました。
kenshirou

2018/12/12 01:37 編集

「遅延バインディングしたくない」ということであれば、本来は、VB→C#にコンバートしたコードについての質問ではなく、「事前バインディングする方法は?」という質問の方が良かったかも知れません。 ただ、残念ながら、"IFD.RW", "ICC.Card", "FeliCa2.API"の情報が少ないので、識者を待つことになるでしょう。 (私は、C#であっても遅延バインドは手軽で便利だと思いますが、それは今回のテーマには関係ないので、これ以上は触れません。)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問