【问题标题】:PInvoking function with output parameter使用输出参数调用函数
【发布时间】:2016-06-30 07:54:25
【问题描述】:

我有以下 C++ 函数:

int my_func(char* error) {
  // Have access here to an Exception object called `ex`
  strcpy(error, ex.what());
  return 0;
}

我在 C# 中这样调用它:

[DllImport("pHash.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern int my_func(
    [MarshalAs(UnmanagedType.LPStr)]
    StringBuilder error);

并在代码中这样使用(当然总是 C#):

StringBuilder error = new StringBuilder();
int returnValue = my_func(error);

如果我运行它,程序会严重崩溃(这意味着毫无例外地崩溃。只是关闭,就是这样)。我做错了什么?

【问题讨论】:

  • Matthew 的回答似乎是正确的。但是对于您的下一个问题:请至少告诉我们错误消息。 “Crashs terribly”不如异常消息好。
  • 也不例外,就是问题所在。程序退出,就是这样......
  • 这个函数的接口坏掉了。您无法防止缓冲区溢出。您必须让调用者传递缓冲区的长度,然后确保您不会复制超出缓冲区的末尾。

标签: c# c++ pinvoke marshalling


【解决方案1】:

这里的问题是:你的代码如何知道字符串缓冲区应该有多大?

通常情况下,您可以通过某种方式找出答案。在没有此信息的情况下,您唯一能做的就是在调用函数之前将 StringBuilder 初始化为您期望的最大字符串。

例如:

     StringBuilder error = new StringBuilder(1024); // Assumes 1024 chars max.

您的代码传递了一个默认容量为(我认为)16 的 StringBuilder,因此任何大于该容量的字符串都会导致崩溃。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-28
    • 2018-08-04
    • 1970-01-01
    • 2019-01-26
    • 2023-03-08
    • 2021-11-01
    • 1970-01-01
    相关资源
    最近更新 更多