簡體   English   中英

從C#到C ++非托管代碼的多個函數調用導致AccessViolationException

[英]Multiple function calls from C# to C++ unmanaged code causes AccessViolationException

我在我的C#程序中聲明了一個DLL導入,如下所示:

[DllImport("C:\\c_keycode.dll", EntryPoint = "generateKeyCode", 
           CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr generateKeyCode(char[] serial, char[] option, char c_type);

它引用了我的DLL里面的函數generateKeyCode()

以下是導致錯誤的代碼(使用的斷點):

const char* generateKeyCode(char serial[], 
                 char option[], 
                 char c_type)
{
returnBufferString = "";
SHA1_CTX context;
int optionLength = 0;
#ifdef WIN32
unsigned char buffer[16384] = {0};
#else
unsigned char buffer[256] = {0}; 

#endif
//char output[80];
char keycode[OPTION_KEY_LENGTH+1]        = "";
int digest_array_size = 10; //default value for digest array size
unsigned char digest[20] = {0};
char optx[24] = {0};
char c_type_upper;
// Combine serial # and Option or Version number

char str1[30] = {0};
int i;
int size = 0;
int pos = 0;


...
...
}

基本上,我導入了這個DLL,所以我可以傳遞函數參數,它可以做它的算法,只需返回一個結果。 我使用了這個封送功能......

public static string genKeyCode_marshal(string serial, string option, char type)
{
    return Marshal.PtrToStringAnsi(generateKeyCode(serial.ToCharArray(), 
           option.ToCharArray(), type));
}

...所以我可以正確地打電話。 在我的C ++頭文件中,我已經定義了一個字符串,正如所指出的那樣有助於回答這個問題 (它是在C / C ++函數頂部出現的returnBufferString變量)。

當我使用NumericUpDown控件從1.0到9.9以0.1為增量(每次向上或向下伴隨另一個函數調用)時,我多次調用此函數,然后再次返回。 但是,每次我嘗試這樣做時,程序會在看似設定數量的函數調用之后掛斷(如果我直接上下移動,則在返回的路上停止在1.9,如果我上下移動一下,則停止更早) 。

請注意,它有效,並給我我想要的價值,那里沒有差異。

我將緩沖區大小更改為更小的數字(5012),當我嘗試運行程序時,在第一個函數調用時它拋出了AccessViolationException。 然而,將緩沖區大小加倍兩倍(32768),與原始緩沖區大小相比沒有任何影響 - 從1.0直接上升至9.9並再次向下,它停在1.9並拋出異常。

編輯:默認為ANSI,因此它是ANSI。 沒有問題。 這是內存分配問題嗎?

我建議嘗試以下方法:

[DllImport("C:\\c_keycode.dll", EntryPoint = "generateKeyCode", 
       CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
static extern IntPtr generateKeyCode(string serial, string option, char c_type);

請注意DllImport屬性的新CharSet字段。

接下來的想法是明確使用MarshalAs屬性:

[DllImport("C:\\c_keycode.dll", EntryPoint = "generateKeyCode", 
       CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto)]
static extern IntPtr generateKeyCode([MarshalAs(UnmanagedType.LPTStr)] string serial, [MarshalAs(UnmanagedType.LPTStr)] string option, char c_type);

我知道這可能是不能令人滿意的,但是一旦我刪除了我用來在我的C / C ++ DLL中調試的輸出重定向,問題就停止了。 現在一切正常,所以我猜這基本上等同於回答我自己的問題。 感謝大家的回復。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM