Вызов неуправляемого кода из потока C # - PullRequest
2 голосов
/ 27 февраля 2011

У меня есть неуправляемая библиотека C ++, для которой я создал управляемую оболочку C ++. Я сейчас пытаюсь вызвать это из C #. Все идет нормально. Однако, когда я пытаюсь вызвать тот же код изнутри в потоке C #, я получаю исключения из неуправляемого кода:

Выражение: нижний индекс вектора вне диапазона

Это вообще возможно? Я предполагаю, что каждый поток получит свой собственный экземпляр неуправляемого класса?

Я искал долго и упорно для получения дополнительной информации о вызывающем неуправляемом коде из потоков, но информация кажется sparce, мягко говоря.

Заранее спасибо за любую помощь

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 # Тема

    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 t1 = new Thread(DcThread);
t1.Start();

Ответы [ 2 ]

1 голос
/ 27 февраля 2011

Управляемые типы в .NET следуют одним и тем же правилам, независимо от того, написаны они на C # или C ++ / CLI.

Хотя можно создать новый экземпляр класса C ++ / CLI для каждого потока, этого не произойдет автоматически, если вы не скажете компилятору, что вам нужно.

РЕДАКТИРОВАТЬ: Глядя на код, я не вижу никаких проблем, кроме утечки памяти. Класс C ++ / CLI должен иметь как деструктор, так и финализатор, например:

!EllipseFit() 
{ 
    delete _unmanagedEllipseFit; 
    _unmanagedElipseFit = nullptr;
}


~EllipseFit() { this->!EllipseFit(); }

Что касается сбоя - возможно, неуправляемый код использует статические или глобальные переменные и, следовательно, не может использоваться одновременно из нескольких потоков.

0 голосов
/ 27 февраля 2011

При создании вашей темы вы можете установить состояние квартиры на STA (обычно полезно для взаимодействия с COM)

Thread thread = new Thread();
thread.SetApartmentState(ApartmentState.STA);
thread.Start(new ThreadStart(DoWork));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...