我有一个像这样的dll之一的c ++调用,
public static extern bool RecognizeEvent(int Id ,long DataLength ,ref object EventData);
我试图以这种方式调用此函数..
Status = oStatus(parameters);
object oiStatus = (object)Status;
bValue = RecognizeEvent(ID, DataLength, ref oiStatus);
其中Status
是struct
。当我试图通过代码我得到跟随错误
Step into: Stepping over method without symbols 'System.Variant.MarshalHelperConvertObjectToVariant'
A first chance exception of type 'System.ArgumentException' occurred
我不确定将struct转换为object是否会抛出此异常。 任何类型的指针将不胜感激
C#的结构:
public struct INBOUND_RADIO_STATUS {
public int wMsgId;
public int channel;
public int unit_id;
public int wStatus;
public int wRadioStatus;
public int wTimeMinutes;
public int wPrimarySetID;
public int wSecondarySetID;
public byte[] individualAlias;
public int wZoneId;
public int wSiteId;
public int dest_unit;
public byte[] destinationAlias;
}
vb 6 struct:
Public Type INBOUND_RADIO_STATUS
wMsgId As Integer
channel As Integer
unit_id As Long
wStatus As Integer
wRadioStatus As Integer
wTimeMinutes As Integer
wPrimarySetID As Integer
wSecondarySetID As Integer
individualAlias(0 To 49) As Byte
wZoneId As Integer
wSiteId As Integer
dest_unit As Long
destinationAlias(0 To 49) As Byte
End Type
答案 0 :(得分:1)
在VB6中,Integer
实际上是2个字节,因此它的.NET等效类型是short
。同样地,Long
是int
。您还需要指定数组的大小,因为它们是固定大小的。你在C#中的结构看起来应该更像这样:
[StructLayout(LayoutKind.Sequential)]
public struct INBOUND_RADIO_STATUS
{
public short wMsgId;
public short channel;
public int unit_id;
public short wStatus;
public short wRadioStatus;
public short wTimeMinutes;
public short wPrimarySetID;
public short wSecondarySetID;
[MarshalAs(UnmanagedType.LPArray, SizeConst=50)]
public byte[] individualAlias;
public short wZoneId;
public short wSiteId;
public int dest_unit;
[MarshalAs(UnmanagedType.LPArray, SizeConst = 50)]
public byte[] destinationAlias;
}
注意顶部的顺序布局属性和特定大小的数组。这应该保证结构与VB6版本的布局/大小相同。
值得注意的是,虽然byte
是值类型,但byte[]
是引用类型,可以是null
。由于您正在编组对象,因此分配的数据大小与非托管代码所需的大小相同非常重要。
您可能还需要使用一些其他属性来装饰C#代码,例如:
public static extern bool RecognizeEvent(int Id ,long DataLength ,[Out] ref object EventData);
另一件事对我来说就是你在结构类型的位置传递object
。这意味着你正在装箱INBOUND_RADIO_STATUS
,基本上把它变成另一种类型。尝试使用实际类型代替object
。拳击可能也会给你一些问题,你应该知道在托管代码和非托管代码之间传递值的含义。