我有一个用C ++编写的dll,我想用C#调用它。该函数输出outputChar和deadChar,deadChar变量也由C ++函数读取。
我试图以不同的方式从C#调用函数,但是我一直得到AccessViolationException:“尝试读取或写入受保护的内存。这通常表明其他内存已损坏。”
C ++ dll:
extern "C" _declspec (dllexport) int convertVirtualKeyToWChar(int virtualKey, PWCHAR outputChar, PWCHAR deadChar);
C#代码1:
[DllImport("keylib.dll")]
static extern int convertVirtualKeyToWChar(int virtualKey,
StringBuilder output,
StringBuilder deadchar);
C#代码2:
static extern int convertVirtualKeyToWChar(int virtualKey,
out char output,
ref char deadchar);
答案 0 :(得分:5)
注意:函数PWCHAR
的两个convertVirtualKeyToWChar
参数不明确。它们可以指向单个WCHAR
或指向WCHAR
字符串的指针。给定函数和参数的名称,这个答案假设它们是指向单个WCHAR
的指针。
您想使用以下内容:
[DllImport("keylib.dll", CharSet=CharSet.Unicode, CallingConvention=CallingConvention.Cdecl)] static extern int convertVirtualKeyToWChar( int virtualKey, out char output, ref char deadchar );
崩溃的原因有两个:DllImport
默认为ANSI字符集和StdCall调用约定。您的C ++ DLL未指定任何调用约定,因此它将默认为CDecl。
请参阅DllImportAttribute.CallingConvention和DllImportAttribute.CharSet
答案 1 :(得分:1)
这是黑暗中的刺,所以警告经纪人 ......
static extern int convertVirtualKeyToWChar(int virtualKey,
char[] output,
char[] deadchar);
将单个元素数组传递给每个char[]
参数。
答案 2 :(得分:0)
试试这个(请记住,如果在Alloc和Free之间抛出异常,你将泄漏内存,因此构建一些错误处理):
static void Main(string[] args)
{
IntPtr pout = Marshal.AllocHGlobal(2);
IntPtr pdead = Marshal.AllocHGlobal(2);
int ret = convertVirtualKeyToWChar(1, pout, pdead);
char output = (char)Marshal.ReadInt16(pout);
char dead = (char)Marshal.ReadInt16(pdead);
Marshal.FreeHGlobal(pout);
Marshal.FreeHGlobal(pdead);
}
static extern int convertVirtualKeyToWChar(int virtualKey,
IntPtr output,
IntPtr deadchar);