简体   繁体   English

从C#线程调用非托管代码

[英]Calling unmanaged code from a C# thread

I have an unmanaged C++ library for which I've created a managed C++ wrapper. 我有一个非托管C ++库,为此我创建了一个托管C ++包装器。 I'm now trying to call this from C#. 我现在正试图从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: 但是,当我尝试从C#线程中调用相同的代码时,会从非托管代码中获取异常:

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 C ++包装器

// 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 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 Start C#线程启动

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. .NET中的托管类型无论使用C#还是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. 尽管可以为每个线程创建C ++ / CLI类的新实例,但是如果您不告诉编译器您想要的,就不会自动发生。

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: C ++ / CLI类应同时具有析构器和终结器,如下所示:

!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. 至于崩溃-也许非托管代码使用静态或全局变量,因此不能在多个线程中同时使用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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