我需要在一个类中拥有一个私有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的开销。我只是想问这个问题。
由于
答案 0 :(得分:2)
从评论中可以看出,您有三种选择:
class
与[SequentialLayout]
一起使用;请参阅MSDN示例。
不要尝试在getData()
中返回整个结构,而只是返回对调用者真正感兴趣的部分。对此的一个变体是传入Func<>
(或Action<>
)来对结构进行操作。这两种技术都避免了复制。
C ++是否适用于C ++;在C ++ / CLI中实现doSomeWork()
而不是C#。这也避免了在C#中从 .h 文件中复制(大)结构。