2012-02-08 45 views
1

我是C#和.NET的新手。我想在.NET中使用我現有的C++ dll,所以我正在嘗試使用interop。我不知道爲什麼會引發這個例外。我知道那個異常意味着什麼,我讀了MSDN,但不知道爲什麼會引發這種情況。爲什麼我在c#/ C++ dll interop期間得到System.AccessViolationException?

我的代碼是這樣的。

該dll代碼是一個簡單的功能,需要一個char*

extern "C" __declspec(dllexport)void test(char *text) 
{ 
// these raise System.AccessViolationException 
// char c = text[0]; 
// int n = strlen(text); 
// char *copy = strdup(text); 
} 

的C#代碼是一個簡單的類調用這個函數

namespace Interop_test 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      char[] text = new char[10]; 
      for (int i = 0; i < 10; i++) 
       text[i] = (char)('A' + i); 
      test(text); 
     } 
     [DllImport("interop_test_dll.dll")] 
     private static extern void test(char[] text); 
    } 
} 

的說,如果在DLL函數中註釋掉的代碼被刪除異常。爲什麼?

如何(或必須)我將C#數據數組傳遞給C++?

從哪裏可以找到有關在C++/C#interop期間處理內存管理的更多信息?

回答

0

使用字符串,試試這個:如果你想改變你的字符串中的測試功能,然後使用ref

private static extern void test(ref string text); 

。否則,你可以離開它。

+0

這適用於此處顯示的代碼,char c = text [0];但其他操作如strdup,strlen等失敗。 – Dirt 2012-02-08 10:30:45

0

你在哪裏在字符串的末尾放置一個零?我認爲沒有在哪裏。我不知道這是否是一個問題,但您可以嘗試將文本的大小增加到11,然後在文本中輸入一個零[10]。

0

這應該可以做到。 CharSet.Ansi並使用實際的字符串。這些是這裏的關鍵。

namespace Interop_test 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      char[] text = new char[10]; 
      for (int i = 0; i < 10; i++) 
       text[i] = (char)('A' + i); 
      test(new string(text)); 
     } 

     [DllImport("interop_test_dll.dll", CharSet = CharSet.Ansi)] 
     private static extern void test(
      [MarshalAs(UnmanagedType.LPStr, CharSet = CharSet.Ansi)] string text); 
    } 
} 
+0

當我嘗試時出現此錯誤。 'System.Runtime.InteropServices.MarshalAsAttribute'不包含'CharSet'的定義 – Dirt 2012-02-08 11:15:11

0

這些文章不會回答您的具體問題,但它們可能會對您有用,因爲您繼續這樣做。

Calling Win32 dlls in .NET with P/Invoke

Default Marshalling for value types

此外,在另外的指示編組類型的dllimport的語句,你可以添加信息,以表明他們是否應該被編組爲輸入或輸出或兩者兼而有之。

[DllImport("interop_test_dll.dll")] 
private static extern void test([MarshalAs(UnmanagedType.LPStr), In, Out]string text); 
相關問題