【问题标题】:Using cpp code in c# (return custom struct and std:string)在 c# 中使用 cpp 代码(返回自定义结构和 std:string)
【发布时间】:2014-12-18 20:17:09
【问题描述】:

我正在尝试构建一个包装器以在 c# 代码中使用 cpp 代码,并且我想返回自定义结构(类)作为方法 2 的输出,以及方法 1 的 std::string,这是我在 cpp 中的代码

extern "C" __declspec(dllexport)  std::string method1()
{
  std::string s;
  //Some Code/////////
  return s;
}

这是应该返回自定义结构(或类)的方法

extern "C" __declspec(dllexport)  MyStruct method2()
{
  MyStruct s;
  //Some Code//////
  return s;
}

我尝试为这两种方法编写 c# 代码,这是我的 c# 代码

[DllImport("<dllPath>", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
[return: MarshalAs(UnmanagedType.LPStr)]
public static extern string  method1(); //Exception

[DllImport("<DllPath>")]
public static extern MyStruct method2(); //Compile Error

现在,当我尝试运行 c# 代码时,我得到了方法 1 的 MarshalDirectiveException 和方法 2 的编译错误?

【问题讨论】:

    标签: c# c++ wrapper


    【解决方案1】:

    在第一个 PInvoke 中,C++ 方法应返回 const char* (s.c_str())。您应该删除“[return [...]]”并将字符串替换为 IntPtr。然后,您可以使用 Marshal.PtrToStringAnsi(ptr) 将 IntPtr 转换为字符串。 http://msdn.microsoft.com/en-US/library/s9ts558h(v=vs.110).aspx可以帮到你。

    在第二个 PInvoke 中,您应该在 C# 中定义 MyStruct(但我不能更准确,因为我没有关于 MyStruct 的信息)。这个链接可以帮助你:http://www.codeproject.com/Articles/66243/Marshaling-with-C-Chapter-Marshaling-Compound-Ty

    编辑:感谢 hvd 的评论,有时最好使用BSTR,因为使用 char* 可能很危险!

    【讨论】:

    • 这不正确。 s是函数返回时销毁的局部变量,s.c_str()返回的指针在s被销毁时不再有效。另外,这不会影响正确性,但是为什么要返回 char * 而不是 const char *
    • 你是对的!我犯了一个错误。我会尽快更正。我以link 为例,但是使用 BSTR link 更好吗?
    • 那将是 OP 应该做出的选择,而不是我应该做出的选择。 :) 返回char * 对于某些用途可能更简单,而对于其他用途可能更复杂。由于问题中的信息有限,无法知道哪个是最好的。
    • 感谢 jd6,但这不起作用!这是 cpp 新代码 extern "C" __declspec(dllexport) const char *method1() ,这是 c# 代码 [DllImport("", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)] public static extern IntPtr method1();但我仍然得到一个例外!
    • 有什么异常?
    猜你喜欢
    • 2013-03-21
    • 1970-01-01
    • 2022-01-21
    • 2012-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-28
    • 2014-10-09
    相关资源
    最近更新 更多