閉じる

アセンブリから STL/CLR コンテナーを公開する

画像処理のソフト作成依頼が来たのが先週。
ぱぱっと C++のコードを書いて、それなりにいけそうな感触。
この時点では先方は C#での納品を希望しているけど、出来れば C++でという話になっていた。
昨日の打ち合わせの結果、基本は C++でいいけど、インターフェース部分は C++/CLIで書いて、C#からも使えるようにという結論に。
インターフェース部分を作るだけで一日かかってしまった。
で、一番はまったのが表題の件。

構造体のコレクションを C++/CLIから C#へ渡すのに cliext::listを使ったのだけど、コレがうまくない。

C++/CLI側では以下のような警告が出るのがよくわからなかったのが最初の点。

warning C4677: 'XXXX': 公開されたメンバーのシグネチャはアセンブリ プライベート型 'cliext::list<YYYY ^>' を含んでいます。

C#側では以下のように言われてビルドすら通らない。

error CS0122: 'XXXX' はアクセスできない保護レベルになっています。
error CS0012: 型 'Microsoft.VisualC.StlClr.IList`1' が参照されていないアセンブリで定義されています。アセンブリ 'Microsoft.VisualC.STLCLR, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' への参照を追加してください。

アクセス権の問題だというのはわかるのだけど、C++/CLIも C#も触るのが今回が初めてで何をどうすればいいのか全くわからない。
cliext::listを使っているのだって、「C++/CLIから C#にコレクションを公開するには cliext::XXXXを使うのが良いらしい」程度しかわかっていない。
いろいろコードを調べた結果、cliext::listが publicになっていないのが原因らしいと言うところまではわかった。
わかったけど、それからどうすれば?と途方に暮れる。

最終的にたどり着いたのが 方法: アセンブリから STL/CLR コンテナーを公開するというページ。
ここの頭に書いてある「テンプレート クラスがアセンブリの境界を越えて使用できないことを意味します。」というのが全てだね。

で、解決策は「System::Collections::Generic::XXXX」を使えと言うことに。

以下のように書いていたのを

public ref struct TResult{
TResult()
{
XXXX=gcnew cliext::list<YYYY^>();
}
cliext::list<YYYY^> ^XXXX;
};

以下のように書くと。

public ref struct TResult{
TResult()
{
XXXX=gcnew cliext::list<YYYY^>();
}
System::Collections::Generic::ICollection<YYYY^> ^XXXX;
};

以上で C#から XXXXがちゃんと参照できるようになる。
コレクションなので foreachも使えるね。

コメントを残す

メールアドレスが公開されることはありません。必須項目には印がついています *

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)