将代码从 vb6 转换为 c#-System.Variant.Marshal Helper 将对象转换为变体'
Converting code from vb6 to c#-System.Variant.Marshal Helper Convert Object To Variant'
我有一个c++调用像这样的一个dll,
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
我不确定将结构体转换为对象是否会抛出此异常。任何形式的指针将不胜感激
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
在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
。装箱可能也会给您带来一些问题,当涉及到在托管代码和非托管代码之间传递值时,您应该了解其含义。
相关文章:
- 在nlohmann json中,如何将嵌套对象的数组转换为嵌套结构的向量
- 将父类对象强制转换为子类的问题
- 将方法转换为调用该方法的成员函子对象会导致崩溃
- 已转换对象的地址
- 如何在OpenGL中使用关键事件来转换对象
- 使用父类实例化的向下转换对象
- 静态强制转换允许转换对象指针,但不允许转换整数
- 为什么类型转换对象不会更改其地址?有关对象类型的信息存储在哪里?
- 找到对象类型后,是否可以使用 static_cast 强制转换对象
- 旨在复制/转换对象的功能系列的模板
- luabind 如何隐式强制转换对象
- 转换对象
- 使用隐式可转换对象调用move重载函数时的编译错误
- 关于在 cpp 中转换对象的两个问题
- 在运行时根据实例变量强制转换对象(c++)
- 使用用户定义的类型强制转换对象
- 在c++中转换对象
- 从"int"到非标量类型赋值运算符的转换 - 对象到 int
- 在屏幕上转换对象可编程管道
- 在 C 样式类型转换期间,关于强制转换对象的地址空间的实际情况