C++ で memleak のないコードを書くことは、私にとっては問題ではありません。RAII のイディオムを守っているだけです。
C# で memleak のないコードを記述することもそれほど難しくありません。ガベージ コレクターがそれを処理します。
残念ながら、C++/CLI コードを書くことは私にとって問題です。仕組みは理解できたと思いますが、まだ大きな問題があります。ヒントを教えていただければ幸いです。
これは私が持っているものです:
内部で C++ ライブラリ (OpenCV など) を使用する、C# で記述された Windows サービス。C++ クラスには、C++/CLI ラッパー クラスを使用してアクセスします。たとえばMatW
、画像オブジェクト用の C++/CLI ラッパー クラスがありcv::Mat
、コンストラクター引数として a を受け取りますSystem::Drawing::Bitmap
。
public ref class MatW
{
public:
MatW(System::Drawing::Bitmap ^bmpimg)
{
cv::Size imgsize(bmpimg->Width, bmpimg->Height);
nativeMat = new Mat(imgsize, CV_8UC3);
// code to copy data from Bitmap to Mat
// ...
}
~MatW()
{
delete nativeMat;
}
cv::Mat* ptr() { return nativeMat; }
private:
cv::Mat *nativeMat;
};
別の C++ クラスは、たとえば
class PeopleDetector
{
public:
void detect(const cv::Mat &img, std::vector<std::string> &people);
}
そしてそのラッパークラス:
public ref class PeopleDetectorW
{
public:
PeopleDetectorW() { nativePeopleDetector = new PeopleDetector(); }
~PeopleDetectorW() { delete nativePeopleDetector; }
System::Collections::Generic::List<System::String^>^ detect(MatW^ img)
{
std::vector<std::string> people;
nativePeopleDetector->detect(*img->ptr(), people);
System::Collections::Generic::List<System::String^>^ peopleList = gcnew System::Collections::Generic::List<System::String^>();
for (std::vector<std::string>::iterator it = people.begin(); it != people.end(); ++it)
{
System::String^ p = gcnew System::String(it->c_str());
peopleList->Add(p);
}
return peopleList;
}
そして、これが私の Windows Service C# クラスのメソッドへの呼び出しです。
Bitmap bmpimg = ...
using (MatW img = new MatW(bmpimg))
{
using (PeopleDetectorW peopleDetector = new PeopleDetector())
{
List<string> people = peopleDetector.detect(img);
}
}
さて、ここに私の質問があります:
- 私のコードに何か問題がありますか?
using
C# コードで使用する必要がありますか? 複数のラッパーオブジェクトが使用されている場合、using
ステートメントをネストする必要があるため、コードが醜くなりますDispose()
オブジェクトを使用した後、代わりに使用できますか?- 気にせず、ガベージコレクターに任せることはできますか?(いいえ
using
、いいえDispose()
) - 上記のコードは、
List<string^>^
C++/CLI から C# などのオブジェクトを返す正しい方法ですか? - using
gcnew
は、ガベージ コレクターがオブジェクトを処理することを意味するのではなく、オブジェクトをいつどのように解放するかを気にする必要はありませんか?
たくさんの質問があることは承知していますが、私が望むのはメモリリークを取り除くことだけなので、うまくいかない可能性があると思われるものをすべてリストしました...