2011-02-26 34 views
2

我有一個非託管C++庫,爲此我創建了一個託管C++包裝器。我現在試圖從C#中調用它。到現在爲止還挺好。然而,當我試圖從內C#的線程我得到的例外來自非託管代碼中調用相同的代碼:從C#線程調用非託管代碼

表達:向量下標越界

這甚至可能嗎?我假設每個線程都會得到它自己的非託管類的實例?

我已經搜索了很長時間,很難找到更多關於從線程中調用非託管代碼的信息,但是信息似乎至少說明了一點。

預先感謝任何幫助

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#線程

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#線程啓動在.NET

Thread t1 = new Thread(DcThread); 
t1.Start(); 
+1

你將不得不表現出一定的C++/CLI代碼爲我們做任何這種感覺。 – 2011-02-26 22:26:22

+0

*編輯*只有當我有多個線程時纔會出現異常。在它的一個線程中,自己沒有其他線程,我沒有看到任何異常。 – 2011-02-26 22:31:48

+0

您是否爲每個線程顯式創建類的單獨實例?當它們不是爲多線程而設計時,共享託管包裝類或非託管本機類是一個很大的禁忌。 – 2011-02-26 22:35:34

回答

1

託管類型遵循相同的規則,沒有馬請確定它們是用C#還是C++/CLI編寫的。

儘管可以爲每個線程創建一個新的C++/CLI類實例,但如果不告訴編譯器這就是您想要的,它不會自動發生。

編輯:看看代碼,除了內存泄漏,我沒有看到任何問題。在C++/CLI類應該有兩個析構函數和終結,就像這樣:

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


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

至於崩潰 - 或許在非託管代碼使用靜態或全局變量,因此不能從多個線程同時使用。

+0

嗨本,我在每個線程中創建一個託管包裝的實例。我只是不明白爲什麼如果每個線程都有它自己的實例,當我運行多個線程時,我會看到不同的行爲.. – 2011-02-26 22:53:07

+0

啊......現在..一個全局變量深入非託管的我的C++代碼似乎是問題。感謝您的幫助! – 2011-02-26 23:47:23

+1

@user:你可能也想要一個'using'語句來確保對象被及時處理。 – 2011-02-26 23:49:36

-1

在創建線程可以設置房間狀態STA(通常爲有用與COM交互)

Thread thread = new Thread(); 
thread.SetApartmentState(ApartmentState.STA); 
thread.Start(new ThreadStart(DoWork)); 
+3

這裏沒有COM,只是純粹的C++互操作。 – 2011-02-27 03:31:45

相關問題