如何将 PWCHAR 传递给 C++来自 C# 的 dll

发布于 2024-10-29 18:16:59 字数 697 浏览 3 评论 0原文

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

I have an dll written in C++, and I want to call it from C#. The function outputs outputChar and deadChar, the deadChar variable is also read by the C++ function.

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++ dll:

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

C# code 1:

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

C# code 2:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

女中豪杰 2024-11-05 18:16:59

注意:函数 convertVirtualKeyToWChar 的两个 PWCHAR 参数不明确。它们可以是指向单个 WCHAR 的指针,也可以是指向 WCHAR 字符串的指针。给定函数和参数的名称,此答案假设它们是指向单个 WCHAR 的指针。

您想使用以下内容:

[DllImport("keylib.dll", CharSet=CharSet.Unicode, CallingConvention=CallingConvention.Cdecl)]
静态 extern int ConvertVirtualKeyToWChar( int virtualKey,
       输出字符,
       参考字符 deadchar );

您的崩溃由两个原因引起:DllImport 默认为 ANSI 字符集和 StdCall 调用约定。您的 C++ DLL 没有指定任何调用约定,因此它将默认为 CDecl。

请参阅 DllImportAttribute.CallingConventionDllImportAttribute.CharSet

Note: The two PWCHAR arguments to your function convertVirtualKeyToWChar are ambiguous. They could be pointers to a single WCHAR or pointers to aWCHAR string. Given the name of the function and arguments, this answer assumes they are pointers to a single 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. Your C++ DLL does not specify any calling convention, so it will default to CDecl.

See DllImportAttribute.CallingConvention and DllImportAttribute.CharSet

ゝ杯具 2024-11-05 18:16:59

这是在黑暗中进行的尝试,所以买者自负...

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

将单元素数组传递给每个 char[] 参数。

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.

倾城月光淡如水﹏ 2024-11-05 18:16:59

尝试一下(请记住,如果在 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);

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):

 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);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文