C#Struct没有无参数构造函数?看看我需要完成什么
我正在使用结构传递到非托管DLL-C#Struct没有无参数构造函数?看看我需要完成什么,c#,dll,constructor,struct,dllimport,C#,Dll,Constructor,Struct,Dllimport,我正在使用结构传递到非托管DLL- [StructLayout(LayoutKind.Sequential)] public struct valTable { public byte type; public byte map; public byte spare1; public byte spare2; public int par;
[StructLayout(LayoutKind.Sequential)]
public struct valTable
{
public byte type;
public byte map;
public byte spare1;
public byte spare2;
public int par;
public int min;
public byte[] name;
public valTable()
{
name = new byte[24];
}
}
上面的代码不会编译,因为VS2005会抱怨“结构不能包含显式的无参数构造函数”。为了将这个结构传递给我的DLL,我必须传递一个结构数组,如sovalTable[]val=newvaltable[281]代码>
我想做的是,当我说new
时,调用构造函数,它创建一个字节数组,就像我试图演示的那样,因为DLL在每个维度中寻找大小为24的字节数组
我怎样才能做到这一点呢?对于你需要做的事情,我认为你真的需要一门课。默认情况下,结构已经实现了无参数构造函数,这就是您无法定义另一个构造函数的原因。结构构造函数与类构造函数类似,但有以下区别:
- 结构不能包含显式
无参数构造函数。结构
成员将自动初始化
设置为其默认值
- 结构不能有初始值设定项
形式为:base(参数列表)
这意味着
A default(parameterless) constructor for a struct could set different
values than the all-zeroed state which would be unexpected behavior. The
.Net Runtime therefore prohabits default constructors for struct.
绕过此场景的典型方法是创建一个静态方法
这将创建您的新实例,以您想要的方式初始化它,然后
归还它。这是在.NET中初始化结构的方法
具有特定的值
ref;
不是最干净的修复方法,但您可以只添加一个参数而不使用它
[StructLayout(LayoutKind.Sequential)]
public struct valTable
{
public byte type;
public byte map;
public byte spare1;
public byte spare2;
public int par;
public int min;
public byte[] name;
public valTable(int x)
{
name = new byte[24];
}
}
您可以使用-我想您确实希望使用-以便在结构中“内联”获取数据(而不是在别处引用数组)
不过,您还需要将结构声明为不安全
请注意,任何需要调用静态方法或提供任何类型的自定义构造函数的“解决方案”都会失败,因为您的明确目标是能够创建这些结构的数组。我建议编写此代码
[StructLayout(LayoutKind.Sequential)]
public struct valTable
{
public byte type;
public byte map;
public byte spare1;
public byte spare2;
public int par;
public int min;
public byte[] name;
static public valTable Create()
{
valTable vT = new valTable();
vT.name = new byte[24];
return vT;
}
}
在此基础上,您可以创建一个静态方法来执行构造函数的工作,如下所示:
[StructLayout(LayoutKind.Sequential)]
public struct valTable
{
public byte type;
public byte map;
public byte spare1;
public byte spare2;
public int par;
public int min;
public byte[] name;
public valTable()
public static valTable NewTable()
{
valTable tbl = new valTable();
tbl.name = new byte[24];
return tbl;
}
}
您将看到.NET Framework中的类已经遵循此模式。我立刻想到了。可能还有其他的。他正在将此结构传递给dll。这是一个错误的答案。。它应该被删除。我投了-1票,因为它促进的代码是误导性的,不太符合逻辑。有更干净的方法可以做到这一点(比如使用静态创建方法)。虚拟参数有点烦人,但并不未知。例如,正常的IDisposable模式有一个伪参数(如果类没有终结器,则永远不应使用“false”值调用其Dispose方法)。请同意。解决方法会产生其他问题,例如buffer.blockcopy和byte[].copyto都会在固定字段上失败。语言限制对于避免常见错误是有意义的,但是“正确”的方法不应该要求编写大量的变通代码。我不知道fixed
关键字可以这样使用,我已经多次想要这样的东西。我…我…我爱你,伙计@杰弗里:不能说我自己用过它,但我必须为C#Depth:)@Mitch:谢谢,我在答案中添加了链接。@Jon Skeet-我有C#Depth,我读过并喜欢它。不知怎的,我错过了那部分。我曾经在一个结构中放入九个整数变量,并使用switch语句模拟数组访问,只是为了得到一个堆栈分配的数组@杰弗里:小心点。很容易出错。看看有什么想法。坦白地说,很多时候我可能会使用你的九整数解。:-)这可能是我的第一个选择,但Jon Skeet的似乎很简单为什么有public valTable()
?net框架对值类型做了两个基本假设:(1)创建任何类型的数组时,除了清空内存外,无需做任何事情;(2) 复制任何类型的字段或变量时,除了复制字节外,无需执行任何操作。一个相关的概念是,执行对象的浅层克隆同样应该什么也不做,只克隆其中任何值类型字段的字节。
[StructLayout(LayoutKind.Sequential)]
public struct valTable
{
public byte type;
public byte map;
public byte spare1;
public byte spare2;
public int par;
public int min;
public byte[] name;
public valTable()
public static valTable NewTable()
{
valTable tbl = new valTable();
tbl.name = new byte[24];
return tbl;
}
}