I have an unmanaged C++ library for which I've created a managed C++ wrapper. I'm now trying to call this from C#. So far so good. However when I try to call the same code from within in a C# thread I get exceptions from within the unmanaged code:
Expression: vector subscript out of range
Is this even possible? I'm assuming each thread would get it's own instance of the unmanaged class?
I've searched long and hard for more information on calling unmanaged code from within threads but info seems sparce to say the least.
Thanks in advance for any help
C++ Wrapper
// Managed wrapper
public ref class EllipseFit
{
private:
// Pointer to unmanaged class
UnmanagedEllipseFit* _unmanagedEllipseFit;
public:
// Constructor & Destructor
EllipseFit()
{
_unmanagedEllipseFit = new UnmanagedEllipseFit();
}
~EllipseFit()
{
delete _unmanagedEllipseFit;
}
开发者_开发问答
List<Ellipse^>^ ProcessImage(array<Byte>^ image, int width, int height)
{
pin_ptr<unsigned char> pimg = &image[0];
_unmanagedEllipseFit->processsImage(pimg, width, height);
// Marshal the results... <edited>
return ellipses;
}
};
C# Thread
private void DcThread()
{
EllipseFit ellipseFit = new EllipseFit();
string fullPath = _fileList.GetNext();
while (fullPath != null)
{
// Load the image
Bitmap bitmap = new Bitmap(fullPath);
byte[] imageData = TsImage.ConvertBitmap(bitmap);
// Process
List<DcEllipse> ellipses = ellipseFit.ProcessImage(imageData, bitmap.Width, bitmap.Height);
// Save the associated text file.. (Debug)
TextWriter textFile = new StreamWriter(fullPath.Replace(".jpg", ".txt"));
foreach (DcEllipse ellipse in ellipses)
textFile.WriteLine(String.Format("{0} {1} {2} {3} {4}", ellipse.X, ellipse.Y, ellipse.MajorAxisLength, ellipse.MinorAxisLength, ellipse.Angle));
textFile.Close();
fullPath = _fileList.GetNext();
}
}
C# Thread Start
Thread t1 = new Thread(DcThread);
t1.Start();
Managed types in .NET follow the same rules, no matter whether they're written in C# or C++/CLI.
While it's possible to create a new instance of the C++/CLI class for each thread, it's not going to happen automatically without you telling the compiler that's what you want.
EDIT: Looking at the code, I don't see any problems apart from a memory leak. The C++/CLI class should have both a destructor and finalizer, like this:
!EllipseFit()
{
delete _unmanagedEllipseFit;
_unmanagedElipseFit = nullptr;
}
~EllipseFit() { this->!EllipseFit(); }
As for the crash -- perhaps the unmanaged code uses static or global variables, and thus can't be used concurrently from multiple threads.
精彩评论