【问题标题】:passing pointers referencing memory allocated in managed code to unmanaged将引用在托管代码中分配的内存的指针传递给非托管
【发布时间】:2013-05-17 14:32:10
【问题描述】:

我在 c# 中分配了一个大的 char[] 缓冲区,并希望将指向此数据的指针传递给 DLL 中的未管理的 c 函数。

现在我认为要使其正常工作,必须修复 char 缓冲区,以便 GC 在函数工作时无法移动它。

如果是这样,我会声明缓冲区 FIXED 并在 UNSAFE 块中调用 DLL 吗??

fixed ( int* p = &bigbuffer )
{
    processbigbuffer(bigbuffer); 
}

我已经搜索过,但没有多少参考文献突出了内存属于 c# 的问题以及这将如何在 DLL 中工作。

谢谢

【问题讨论】:

    标签: c#


    【解决方案1】:

    您不必使用fixed。运行时会自动为您执行此操作。所以如果你有 C 函数:

    void ProcessBigBuffer(char* buffer);
    

    那么您的托管原型将如下所示:

    [DllImport("foo.dll", CallingConvention=CallingConvention.Cdecl)]
    static extern void ProcessBigBuffer([MarshalAs(UnmanagedType.LPArray)] char[] buffer);
    

    您的呼叫站点将是:

    char[] buffer = new char[bufferSize];
    // initialize the buffer
    // and then process it
    ProcessBigBuffer(buffer);
    

    另见:

    【讨论】:

    • 如果您不介意添加问题。在行中 static extern void ProcessBigBuffer([MarshalAs UnmanagedType.LPArray] buffer);为什么那里有一个实际的对象(缓冲区)。如果这是一个函数原型,似乎只需要声明类型。我不怀疑你的回答,我以前见过很多次,只是好奇。这是否意味着我只能使用名为“缓冲区”的变量调用函数
    • @KelseyBowman:C# 规范要求您为参数提供名称。那只是一个正式的名字。您可以在调用站点调用任何您喜欢的缓冲区。也就是说,你可以写ProcessBigBuffer(bigArrayOfInts);。当您声明抽象方法时,您会在 C# 中看到同样的情况。见msdn.microsoft.com/en-us/library/aa664435(v=vs.71).aspx
    • 有没有办法在不创建缓冲区副本的情况下做到这一点?
    • @280Z28:你确定吗?此处接受的答案:stackoverflow.com/q/2218444/56778 另有说明,并且有一个 MSDN 链接,似乎表明该阵列将被固定。
    • @JimMischel 我弄错了。我描述的行为不适用于数组元素类型是原始类型或IntPtr/UIntPtr。它确实适用于用户定义的值类型,即使值类型像struct Foo { int value; } 一样简单,其中本机代码的参数是Foo[]
    【解决方案2】:

    是的,确实如此。您可以在没有不安全代码和复制数据的情况下执行此操作。

    var chars = new char[LARGE_AMOUNT];
    
    var handle = GCHandle.Alloc(chars);
    try
    { 
        processBigBuffer(/* this is an IntPtr -> */ handle.AddrOfPinnedObject, ... );
    }
    finally
    {
        handle.Free();
    }
    

    我的OpenCL 绑定在所有地方都使用它(并且非常高效)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-07-12
      • 1970-01-01
      • 1970-01-01
      • 2011-02-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-21
      相关资源
      最近更新 更多