普段はあんまりやらないのだが、いずれ必要になるかなと思って題名の方法について調べたら、ググってもろくな情報が出て来ないことに気づいた。結構需要はあるらしく(Cで書かれたコード資産の膨大さを考えれば当然だ)、あっちこっちの掲示板でネタに上がっているのだが、一向にまともな回答がなされていないわけである。挙句の果てに「そんなことはできない」などと回答者が無能をさらけ出していたり、あるいは「COMモデルがどうのこうの」と仰々しい話に(例示されているコードがまた、おどろおどろしい)オチていたりする。
しまいにバカらしくなって自分で作ってみたら、結構簡単にできてしまったので紹介しよう。
ポイントは「CからC#を呼び出す」ということの字義にこだわらないことである。もともとC#の方がそういう風にできていない(実に愚かな設計だ!)のだから、直接呼び出すのには無理があるのである。じゃあどうするか。普通誰でもこうするだろうという方法のひとつは、C#からC関数(DLL)を呼び出すことはいたって簡単にできる(そうでないとWindowsのAPIとか呼び出せないから、この機能は必須なのである)わけである。ならば、呼び出し関係を裏返しに使って、あたかもCからC#を呼び出しているかのような(実際にはC#がC関数を呼び出している)格好を作ってしまえばいいのである。
(以降ソースと説明は削除。6月9日の「真」の方を参照されたい)
以上はせいぜい整数型のパラメタ/戻り値の受け渡しをやってるだけだが、適当に手を加えればどんな複雑な構造でも受け渡しすることは可能になるはずである。ただC#の方はマーシャリングといって大きなデータは素直に渡ってくれない(わざわざマネージ領域からアンマネージ領域に、あるいは逆に、データをコピーするわけである。ああ愚かしい)。そのオーバヘッドが嫌だ、という場合は.net 4.0で導入されたメモリマップトファイルを使ってデータの受け渡しをするという方法も考えられる。
こんなのを自分で作れるのに何で最初はググって調べていたのかって、それはもちろん、もっと素直で簡単な方法があるに違いないと思ったから調べていたのである。上の方法は簡単ではあるが、それでもトリッキーな方法には違いないわけで、ここ一番これしかないという時でなければあまり使いたくない方法である。(以降削除)
しまいにバカらしくなって自分で作ってみたら、結構簡単にできてしまったので紹介しよう。
ポイントは「CからC#を呼び出す」ということの字義にこだわらないことである。
(以降ソースと説明は削除。6月9日の「真」の方を参照されたい)
以上はせいぜい整数型のパラメタ/戻り値の受け渡しをやってるだけだが、適当に手を加えればどんな複雑な構造でも受け渡しすることは可能になるはずである。ただC#の方はマーシャリングといって大きなデータは素直に渡ってくれない(わざわざマネージ領域からアンマネージ領域に、あるいは逆に、データをコピーするわけである。ああ愚かしい)。そのオーバヘッドが嫌だ、という場合は.net 4.0で導入されたメモリマップトファイルを使ってデータの受け渡しをするという方法も考えられる。
こんなのを自分で作れるのに何で最初はググって調べていたのかって、それはもちろん、もっと素直で簡単な方法があるに違いないと思ったから調べていたのである。上の方法は簡単ではあるが、それでもトリッキーな方法には違いないわけで、ここ一番これしかないという時でなければあまり使いたくない方法である。(以降削除)