在C#和C ++之间使用双精度数组数据进行P / Invoke

威尔伯特

我在这里这里都已经阅读了使用P / Invoke在C ++ Interop上的各种MSDN页面,但我仍然感到困惑。

我需要进入本地代码的一些大双打数组,以及一些需要返回的结果数组。我不知道输出数组的大小。为简单起见,在示例中,我将只使用一个数组。平台是x64;我读到,在32位和64位环境中,内部编组内部有很大差异,因此这可能很重要。

C#

    [DllImport("NativeLib.dll")]
    public static extern void ComputeSomething(double[] inputs, int inlen, 
        [Out] out IntPtr outputs, [Out] out int outlen);

    [DllImport("NativeLib.dll")]
    public static extern void FreeArray(IntPtr outputs);

    public void Compute(double[] inputs, out double[] outputs)
    {           
        IntPtr output_ptr;
        int outlen;
        ComputeSomething(inputs, inputs.Length, out output_ptr, out outlen);

        outputs = new double[outlen];
        Marshal.Copy(output_ptr, outputs, 0, outlen);

        FreeArray(output_ptr);
    }

C ++

extern "C" 
{
    void ComputeSomething(double* inputs, int input_length, 
        double** outputs, int* output_length)
    {
    //...
    *output_length = ...;
    *outputs = new double[output_length];
    //...
    }

    void FreeArray(double* outputs)
    {
        delete[] outputs;
    }
}

它可以工作,也就是说,我可以读出我在C ++端写入数组的双打。但是,我想知道:

  • 这是使用P / Invoke的正确方法吗?
  • 我的签名不是不必要地复杂吗?
  • 可以更有效地使用P / Invoke解决此问题吗?
  • 我相信我读过,可以避免对内置类型的一维数组进行编组。有没有办法解决Marshal.Copy?

请注意,我们有一个可用的C ++ / Cli版本,但是第三方库代码中与本地静态变量有关的一些问题会导致崩溃。Microsoft将此问题标记为WONTFIX,这就是为什么我要寻找替代方法。

戴维·赫弗南

如果将确定输出长度的代码与填充输出的代码分开是可行的,则可以:

  • 导出返回输出长度的函数。
  • 从C#代码中调用它,然后分配输出缓冲区。
  • 再次调用非托管代码,这一次要求它填充输出缓冲区。

但是我假设您已经拒绝了此选项,因为它不切实际。在这种情况下,您的代码是解决问题的完全合理的方法。实际上,我会说您做得很好。

修复调用约定不匹配后,该代码在x86中将完全相同。在C ++方面,调用约定是cdecl,但在C#方面是stdcall在x64上这无关紧要,因为只有一种调用约定。但这在x86下是个问题。

一些评论:

  • 您不需要使用[Out]以及out后者意味着前者。
  • 您可以通过分配共享堆来避免导出解除分配器。例如CoTaskMemAlloc在C ++方面,然后Mashal.FreeCoTaskMem在C#方面进行释放

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

无法在C#中使用Invoke()和BeginInvoke()更新UI

来自分类Dev

无法在C#中使用Invoke()和BeginInvoke()更新UI

来自分类Dev

如何使用p / invoke终止C#调用的C ++函数

来自分类Dev

如何使用P / Invoke在C#中返回列表?

来自分类Dev

使用P / Invoke的c#调用方法导致AccessViolation异常

来自分类Dev

使用P / Invoke从C#将“ EGLRenderResolutionScaleProperty”编组到ANGLE

来自分类Dev

Parallel.Invoke 和 Dispatcher.Invoke 之间的死锁

来自分类Dev

使用P / Invoke跨C ++ / C#边界管理非托管字符串

来自分类Dev

如何在C#中始终将双精度或双精度数组转换为双精度数组

来自分类Dev

在结构和指针上使用P / Invoke

来自分类Dev

什么是“使用???” 使用 NUGET HDF.P/Invoke 的 C# 中的语句?

来自分类Dev

大型数组的P / Invoke调用上的c#System.ExecutionEngineError

来自分类Dev

Java和C#之间的双原始精度差异

来自分类Dev

枚举/结构的P / Invoke和NativeMethods约定

来自分类Dev

枚举/结构的P / Invoke和NativeMethods约定

来自分类Dev

如何在没有P / Invoke的情况下从c#创建挂起的进程?

来自分类Dev

获取通过C#中的P / Invoke调用加载的库路径

来自分类Dev

获取通过C#中的P / Invoke调用加载的库路径

来自分类Dev

在对C到C#使用P / Invoke并将C struct混搭到C#时,会生成AccessViolationException,这可能是什么原因?

来自分类Dev

C#中的多线程使用Invoke方法给出错误

来自分类Dev

C# 消息:需要一个对象引用(使用 Control.Invoke)

来自分类Dev

C#:this.Invoke((MethodInvoker)委托

来自分类Dev

在C#中将对象数组的对象转换为几个双精度数组

来自分类Dev

azure网站是否支持p / invoke以加载本机c ++ dll

来自分类Dev

当_Out_参数可以为NULL或非NULL时,使用P / Invoke在C#中调用Win API

来自分类Dev

C ++:从指针获取迭代器到双精度数组

来自分类Dev

C ++多维双精度数组未按预期工作

来自分类Dev

在C中将文件(txt)拆分为双精度数组

来自分类Dev

JAVA -JNA C函数修改双精度数组

Related 相关文章

  1. 1

    无法在C#中使用Invoke()和BeginInvoke()更新UI

  2. 2

    无法在C#中使用Invoke()和BeginInvoke()更新UI

  3. 3

    如何使用p / invoke终止C#调用的C ++函数

  4. 4

    如何使用P / Invoke在C#中返回列表?

  5. 5

    使用P / Invoke的c#调用方法导致AccessViolation异常

  6. 6

    使用P / Invoke从C#将“ EGLRenderResolutionScaleProperty”编组到ANGLE

  7. 7

    Parallel.Invoke 和 Dispatcher.Invoke 之间的死锁

  8. 8

    使用P / Invoke跨C ++ / C#边界管理非托管字符串

  9. 9

    如何在C#中始终将双精度或双精度数组转换为双精度数组

  10. 10

    在结构和指针上使用P / Invoke

  11. 11

    什么是“使用???” 使用 NUGET HDF.P/Invoke 的 C# 中的语句?

  12. 12

    大型数组的P / Invoke调用上的c#System.ExecutionEngineError

  13. 13

    Java和C#之间的双原始精度差异

  14. 14

    枚举/结构的P / Invoke和NativeMethods约定

  15. 15

    枚举/结构的P / Invoke和NativeMethods约定

  16. 16

    如何在没有P / Invoke的情况下从c#创建挂起的进程?

  17. 17

    获取通过C#中的P / Invoke调用加载的库路径

  18. 18

    获取通过C#中的P / Invoke调用加载的库路径

  19. 19

    在对C到C#使用P / Invoke并将C struct混搭到C#时,会生成AccessViolationException,这可能是什么原因?

  20. 20

    C#中的多线程使用Invoke方法给出错误

  21. 21

    C# 消息:需要一个对象引用(使用 Control.Invoke)

  22. 22

    C#:this.Invoke((MethodInvoker)委托

  23. 23

    在C#中将对象数组的对象转换为几个双精度数组

  24. 24

    azure网站是否支持p / invoke以加载本机c ++ dll

  25. 25

    当_Out_参数可以为NULL或非NULL时,使用P / Invoke在C#中调用Win API

  26. 26

    C ++:从指针获取迭代器到双精度数组

  27. 27

    C ++多维双精度数组未按预期工作

  28. 28

    在C中将文件(txt)拆分为双精度数组

  29. 29

    JAVA -JNA C函数修改双精度数组

热门标签

归档