如何从C#将PWCHAR传递给C ++ DLL

时间:2011-04-02 23:27:46

标签: c# c++ dll pinvoke dllimport

我有一个用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);

3 个答案:

答案 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.CallingConventionDllImportAttribute.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);