【问题标题】:std::string in C#?C#中的std :: string?
【发布时间】:2010-10-26 20:23:38
【问题描述】:

我认为问题出在我的 C++ 函数中,但我试过了

C++ dll 中的 C++ 函数:

bool __declspec( dllexport ) OpenA(std::string file)
{
return true;
}

C#代码:

[DllImport("pk2.dll")]
public static extern bool OpenA(string path);

    if (OpenA(@"E:\asdasd\"))

我收到内存损坏的异常,为什么?

如果我删除 std::string 参数,效果很好,但使用 std::string 就不行了。

【问题讨论】:

  • 也许您可以通过创建一个解包字符串的托管 c++ 桥来解决它? Here 是关于这个主题的一个 SO 问题。

标签: c# c++ dll


【解决方案1】:

std::string 和 c# string 不兼容。据我所知,就互操作而言,c# 字符串对应于在 c++ 中传递 char*wchar_t*
造成这种情况的原因之一是 std::string 可以有许多不同的实现,而 c# 不能假设您正在使用任何特定的实现。

【讨论】:

  • 更不用说 std::string 也是一个模板,它为互操作打开了另一个有趣的蠕虫罐。
  • 最合适的方法是使用 char* 并从中创建 std::string 。如果要将 std::string 返回到 C#,则必须使用 CoTaskMemAlloc 分配一个大小为 std::string 的 size()+1 的 char*,然后 memcpy std::string 的 data() 到此缓冲区中并返回它。简单。注意:你必须使用 CoTaskMemAlloc!
【解决方案2】:

试试这样的:

bool __declspec( dllexport ) OpenA(const TCHAR* pFile)
{ 
   std::string filename(pFile);
   ...
   return true;
}

您还应该在 DllImport 属性中指定适当的字符集(unicode/ansi)。

顺便说一句,与您的编组问题无关,通常会将 std:string 作为 const 引用传递:const std:string& 文件名。

【讨论】:

  • 如果定义了 _UNICODE,std::string 将无法编译。可能会更好地执行 #ifdef 并使用 std::wstring 或简单地根据 _UNICODE 为 tstring 创建一个 typedef。
【解决方案3】:

不可能以您尝试的方式编组 C++ std::string。您在这里真正需要做的是编写一个包装函数,它使用一个普通的旧 const char* 并在后台转换为 std::string。

C++

extern C { 
  void OpenWrapper(const WCHAR* pName) {
    std::string name = pName;
    OpenA(name);
  }
}

C#

[DllImport("pk2.dll")]
public static extern void OpenWrapper( [In] string name);

【讨论】:

    【解决方案4】:

    std::wstring 和 System.string 可以通过以下转换兼容:

    C++:

    bool func(std::wstring str, int number)
    {
      BSTR tmp_str = SysAllocStringLen(str.c_str(), str.size());
      VARIANT_BOOL ret = VARIANT_FALSE;
    
      // call c# COM DLL
      ptr->my_com_function(tmp_str, number, &ret);
    
      SysFreeString(tmp_str);
    
      return (ret != VARIANT_FALSE) ? true : false;
    }
    

    【讨论】:

      【解决方案5】:

      我知道这个话题有点老了,但对于未来的谷歌人来说,这也应该可以工作(在 C++ 中不使用 char*)

      C#:

      public static extern bool OpenA([In, MarshalAs(UnmanagedType.LPStr)] path);
      

      C++:

      bool __declspec( dllexport ) OpenA(std::string file);
      

      【讨论】:

      • 什么意思?你试过上面的代码还是不行?
      • 我的意思是,有没有说明它应该工作的参考页面,并定义了它工作的要求?
      • 很抱歉,我找不到此 atm 的参考资料(这是很久以前的事了)。但是你可以试试这个页面:msdn.microsoft.com/en-us/library/s9ts558h%28v=vs.110%29.aspx
      猜你喜欢
      • 1970-01-01
      • 2011-07-26
      • 2020-11-04
      • 2020-01-04
      • 2012-10-12
      • 2011-05-02
      • 2013-11-19
      • 1970-01-01
      • 2013-08-26
      相关资源
      最近更新 更多