2011-03-29 47 views
-1

在我的C#.Net應用程序中,我使用C++ DLL和DllImport。
C++的DLL包含枚舉定義:在.net應用程序崩潰的C++枚舉

enum mode { A, B, C }; 

class myClass { 
    char name[512]; 
    mode myMode; //variables beneath this line cause crash 
    char pass[512]; 
}; 

我定義我的C#.NET應用程序相同enum

public enum mode { A, B, C }; 

現在,如果我訪問是myMode之後定義的myclass變量行,我得到一個內存損壞錯誤:

getName(); //ok 
getPass(); //error 

extern "C" LPCTSTR FAR PASCAL EXPORT getPass() { return myC->pass; } 

C#包裝:

[DllImport(DLLNAME)] 
public static extern string GetPass(); 

作爲一種變通方法我用int類型爲myMode和一切正常。但我很好奇如何做對。

+0

C++枚舉是編譯時的「虛構」(就像內聯函數和模板一樣)。編譯後,它們與整數無法區分。 C++抽象是[特別泄漏](http://www.joelonsoftware.com/articles/LeakyAbstractions.html)。 – pyon 2011-03-29 14:36:03

+0

Ew ... C++中的'char []'真的很醜。順便說一句,可能會有一個緩衝區溢出,因爲'name'長度可能大於512.在這種情況下'name'(和'myMode')之後的所有成員都將被破壞。只是一個建議,沒有看到實際的代碼,但 – maverik 2011-03-29 15:19:29

+0

@maverik:沒有緩衝區溢出。我使用簡單的測試值。 – 2011-03-30 06:54:00

回答

2

您寫道:

// .cpp 
extern "C" LPCTSTR FAR PASCAL EXPORT getPass() { return myC->pass; } 

// .cs 
[DllImport(DLLNAME)] 
public static extern string GetPass(); 

的E w ...如果這是

[DllImport(DLLNAME)] 
public static extern string getPass(); 

我不知道C#是大小寫敏感與否,但據我所知它。

我無法理解的另一個技巧是LPCTSTR。因爲使用char[],是否應該是LPCSTR?而且,嗯...... C#真的需要PASCAL慣例嗎?

+0

它的一箇舊的DLL,我想FAR和PASCAL不再需要了。我對錯誤的拼寫感到抱歉:它應該是C#和C++中的getPass()。但問題不在於此。我至少得到了20個具有相同簽名的getter方法,但只有那些在模式行崩潰後返回內容的getter方法。 – 2011-03-30 14:27:26

+0

我有一招。如果你可以執行以下操作會很有幫助:將'mode'聲明爲'枚舉模式{A = 0xFFFFFFF0,B = 0xFFFFFFF1,C = 0xFFFFFFF2};'並檢查應用程序是否崩潰。不要忘記告訴我們結果。 – maverik 2011-03-30 14:33:14

+0

它會崩潰,如果我做你的建議。有趣的是getMode()調用起作用,但getPass()調用不起作用。更奇怪的是,它取決於模式myMode在我的班級中的位置。 – 2011-03-31 06:32:15