c#Struct Ref以防止复制

时间:2015-02-10 16:16:41

标签: c# struct copy ref

我需要在一个类中拥有一个私有struct成员,并且正在寻找一种方法来访问这个struct成员,而不需要执行副本。

原因是该结构用作c dll的接口。

public class MyCDllApi
{
    // Marshalled struct
    [StructLayout(LayoutKind.Sequential)]
    public struct DllData
    {
        [MarshalAs(UnmanagedType.U1)] public byte data1;
        [MarshalAs(UnmanagedType.U1)] public byte data2;
        // ...
        // lots more; this is really a LARGE struct
    }

    // DLL Function call
    [DllImport("MyC.dll",  CallingConvention=CallingConvention.Cdecl)]
    private static extern int do_some_work(ref DllData data);

    public void doSomeWork()
    {
        do_some_work(ref m_dllData);
    }
    public DllData getData();

    private DllData m_dllData;
}

public class MyProg
{
    static void Main(String args[])
    {
        MyC_DllApi m_dllApi = new MyCDllApi();
        m_dllApi.doSomeWork();
        DllData data = m_dllApi.getData();

        // Use data
    }
}

我原以为我可以装入结构并从getData()返回一个对象,但这意味着需要进行强制转换。

我还在想我可以在类中包含结构,这可以作为引用传递,但是为检索结构成员而提供的任何方法都会执行副本。

另一个想法是将m_dllData公开。

有人可以告诉我在c#中这种情况下的正常解决方案,即相当于返回“const&”在C ++中。出于性能原因,我是否愿意避免创建结构的副本?我可以通过ref将结构作为函数参数传递。我可以不将ref返回给类成员结构吗?

修改

只是为了澄清,在这种情况下我使用的是结构,因为这符合DLL的API,我认为与此API保持一致是件好事。我不是要求用类替换它的方法。同样,我也不是在寻找一种能让课程变得更复杂的解决方案。

我希望MyCDllApi成为C dll的一个简单的非智能c#包装器。我问每次外部对象访问此类以检索DllData时是否有任何合理的方法来避免struct copy。即以与“const&”类似的方式在C ++中。

如果这种解决方案/模式在C#中不常用或不合适,那么这很好。我的程序可以处理struct copy的开销。我只是想问这个问题。

由于

1 个答案:

答案 0 :(得分:2)

从评论中可以看出,您有三种选择:

  1. class[SequentialLayout]一起使用;请参阅MSDN示例。

  2. 不要尝试在getData()中返回整个结构,而只是返回对调用者真正感兴趣的部分。对此的一个变体是传入Func<>(或Action<>)来对结构进行操作。这两种技术都避免了复制。

  3. C ++是否适用于C ++;在C ++ / CLI中实现doSomeWork()而不是C#。这也避免了在C#中从 .h 文件中复制(大)结构。