简体   繁体   中英

Calling unmanaged code from a C# thread

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM