【问题标题】:How to pass strings from C# to C++ (and from C++ to C#) using DLLImport?如何使用 DLLImport 将字符串从 C# 传递到 C++(以及从 C++ 到 C#)?
【发布时间】:2012-06-03 17:00:01
【问题描述】:

很长一段时间以来,我一直在尝试向/从 C# 向/从 C++ 发送一个字符串,但还没有设法让它工作......

所以我的问题很简单:
有谁知道将字符串从 C# 发送到 C++ 以及从 C++ 发送到 C# 的某种方法?
(一些示例代码会有所帮助)

【问题讨论】:

    标签: c# c++ string dllimport


    【解决方案1】:

    Windows API 中遇到的许多函数都采用字符串或字符串类型的参数。对这些参数使用字符串数据类型的问题在于,.NET 中的字符串数据类型一旦创建就不可更改,因此 StringBuilder 数据类型是这里的正确选择。例如,检查 API 函数 GetTempPath()

    Windows API 定义

    DWORD WINAPI GetTempPath(
      __in   DWORD nBufferLength,
      __out  LPTSTR lpBuffer
    );
    

    .NET 原型

    [DllImport("kernel32.dll")]
    public static extern uint GetTempPath
    (
    uint nBufferLength, 
    StringBuilder lpBuffer
    );
    

    用法

    const int maxPathLength = 255;
    StringBuilder tempPath = new StringBuilder(maxPathLength);
    GetTempPath(maxPathLength, tempPath);
    

    【讨论】:

      【解决方案2】:

      在你的 c 代码中:

      extern "C" __declspec(dllexport)
      int GetString(char* str)
      {
      }
      
      extern "C" __declspec(dllexport)
      int SetString(const char* str)
      {
      }
      

      在.net端:

      using System.Runtime.InteropServices;
      
      
      [DllImport("YourLib.dll")]
      static extern int SetString(string someStr);
      
      [DllImport("YourLib.dll")]
      static extern int GetString(StringBuilder rntStr);
      

      用法:

      SetString("hello");
      StringBuilder rntStr = new StringBuilder();
      GetString(rntStr);
      

      【讨论】:

      • 您的const 使用倒退了。
      • 这些示例在 VisStudio 2012 中因堆栈异常而爆炸,直到我将 cdecl 添加到 C# 和 C.... extern "C" __declspec(dllexport) int __cdecl SetString(... 然后 . .. [DllImport("YourLib.dlll", CallingConvention = CallingConvention.Cdecl)]...
      【解决方案3】:

      将字符串从 C# 传递到 C++ 应该是直截了当的。 PInvoke 将为您管理转换。

      可以使用 StringBuilder 将字符串从 C++ 获取到 C#。您需要获取字符串的长度才能创建正确大小的缓冲区。

      以下是众所周知的 Win32 API 的两个示例:

      [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
       static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
      public static string GetText(IntPtr hWnd)
       {
           // Allocate correct string length first
           int length       = GetWindowTextLength(hWnd);
           StringBuilder sb = new StringBuilder(length + 1);
           GetWindowText(hWnd, sb, sb.Capacity);
           return sb.ToString();
       }
      
      
      [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
       public static extern bool SetWindowText(IntPtr hwnd, String lpString);
      SetWindowText(Process.GetCurrentProcess().MainWindowHandle, "Amazing!");
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-09-09
        • 2012-02-12
        • 1970-01-01
        • 2015-12-23
        • 2012-04-06
        • 2014-11-01
        相关资源
        最近更新 更多