简体   繁体   English

如何从C#将PWCHAR传递到C ++ dll

[英]How to pass PWCHAR to C++ dll from C#

I have an dll written in C++, and I want to call it from C#. 我有一个用C ++编写的dll,我想从C#中调用它。 The function outputs outputChar and deadChar, the deadChar variable is also read by the C++ function. 该函数输出outputChar和deadChar,C ++函数也会读取deadChar变量。

I tried to call function from C# in different ways, but all time I got AccessViolationException: "Attempted to read or write protected memory. This is often an indication that other memory is corrupt." 我试图以不同的方式从C#调用函数,但始终遇到AccessViolationException:“试图读取或写入受保护的内存。这通常表明其他内存已损坏。”

C++ dll: C ++ dll:

extern "C" _declspec (dllexport) int convertVirtualKeyToWChar(int virtualKey, PWCHAR outputChar, PWCHAR deadChar);

C# code 1: C#代码1:

[DllImport("keylib.dll")]
static extern int convertVirtualKeyToWChar(int virtualKey,
               StringBuilder output,
               StringBuilder deadchar);

C# code 2: C#代码2:

static extern int convertVirtualKeyToWChar(int virtualKey,
           out char output,
           ref char deadchar);

Note: The two PWCHAR arguments to your function convertVirtualKeyToWChar are ambiguous. 注意:函数convertVirtualKeyToWChar的两个PWCHAR参数是不明确的。 They could be pointers to a single WCHAR or pointers to a WCHAR string. 它们可以是指向单个WCHAR指针,也可以是指向WCHAR字符串的指针。 Given the name of the function and arguments, this answer assumes they are pointers to a single WCHAR . 给定函数和参数的名称,此答案假定它们是指向单个WCHAR指针。

You want to use the following: 您要使用以下内容:

 [DllImport("keylib.dll", CharSet=CharSet.Unicode, CallingConvention=CallingConvention.Cdecl)] static extern int convertVirtualKeyToWChar( int virtualKey, out char output, ref char deadchar ); 

Your crash is caused by two reasons: DllImport defaults to the ANSI character set and StdCall calling convention. 您的崩溃是由两个原因引起的: DllImport默认为ANSI字符集和StdCall调用约定。 Your C++ DLL does not specify any calling convention, so it will default to CDecl. 您的C ++ DLL没有指定任何调用约定,因此它将默认为CDecl。

See DllImportAttribute.CallingConvention and DllImportAttribute.CharSet 请参阅DllImportAttribute.CallingConventionDllImportAttribute.CharSet

This is a stab in the dark, so caveat emptor ... 这是在黑暗中的刺伤,所以请告诫 ...

static extern int convertVirtualKeyToWChar(int virtualKey,
                                           char[] output,
                                           char[] deadchar);

Pass a single-element array to each char[] parameter. 将单元素数组传递给每个char[]参数。

Try this (bearing in mind that if an exception is thrown between Alloc and Free you will leak memory, so build some error handling in): 尝试以下操作(请记住,如果在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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM