![](/img/trans.png)
[英]AccessViolationException when accessing unmanaged C++ DLL with C#
[英]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.