方法原型:
virtual HRESULT STDMETHODCALLTYPE Read(
/* [in] */ IItemIdentity *IdItems,
/* [in] */ unsigned int ItemsCount,
/* [out] */ DataUpdate **pDataUpdates,
/* [retval][out] */ unsigned int *UpdatesCount) = 0;
参数“IItemIdentity”结构体原型:
typedef struct _IItemIdentity {
WCHAR *ContextName;
unsigned __int64 Id;
WCHAR *Name;
int ReferenceType;
int Type;
} IItemIdentity;
参数“DataUpdate ”结构体原型:
typedef struct _DataUpdate {
unsigned __int64 ItemId;
unsigned long StatusCode;
FILETIME Timestamp;
unsigned long Quality;
IVariant Value;
} DataUpdate;
参数“IVariant”结构体原型:
typedef struct _IVariant {
int Length;
IWS_BYTES Payload;
int Type;
} IVariant;
参数“IWS_BYTES ”结构体原型:
typedef struct _IWS_BYTES {
ULONG length;
BYTE *bytes;
} IWS_BYTES;
=====================================
C#调用:
参数“DataUpdate”结构体转换到C#结构体如下:
//To C# structure
[StructLayout(LayoutKind.Explicit)]
public struct DataUpdate
{
[FieldOffset(0)]
public Int64 ItemId;
[FieldOffset(0)]
public Int32 Quality;
[FieldOffset(0)]
public Int32 StatusCode;
[FieldOffset(0)]
MXDATACONSUMERLib._FILETIME Timestamp;
[FieldOffset(0)]
MXDATACONSUMERLib._IVariant Value;
}
MXDATACONSUMERLib.IDataClient iDataClient = new MXDATACONSUMERLib.DataClient();
//Read one or more items registered.
public List<long> Read(ref List<MXDATACONSUMERLib._IItemIdentity> itemIdentitys, out List<DataUpdate> itemDataUpdates, out string error)
{
error = null;
itemDataUpdates = null;
List<DataUpdate> tempDataUpdate = new List<DataUpdate>();
uint itemid = 0;
int m = 0;
List<long> list = new List<long>();
DataUpdate dataUpdate = new DataUpdate();
IntPtr dataUpdatePtr = Marshal.AllocHGlobal(Marshal.SizeOf(dataUpdate));
Marshal.StructureToPtr(dataUpdate, dataUpdatePtr, false);
try
{
foreach (MXDATACONSUMERLib._IItemIdentity itemIdentity in itemIdentitys)
{
itemid = iDataClient. Read(itemIdentity, 1, dataUpdatePtr);
list.Add(itemid);
dataUpdate = (DataUpdate)Marshal.PtrToStructure(dataUpdatePtr, typeof(DataUpdate));
tempDataUpdate.Insert(m, dataUpdate);
itemDataUpdates = tempDataUpdate;
m = m + 1;
}
}
catch (SystemException se)
{
error = se.Message.ToString();
}
return list;
}
调用Read(...)方法最后提示“The operation did not complete within the time allotted. (Exception from HRESULT: 0x803D0006)”
本人没有完过C#调用C++ Com方法,不知哪位“大虾”能解燃眉之急,跪谢!
7 个解决方案
#1
楼主,你明白[FieldOffset(0)]的意思吗?
既然是COM组件,那么它里面的涉及的数据类型:IItemIdentity 、DataUpdate 、FILETIME 、_IVariant、_IWS_BYTES等会自然在IDL接口里面声明,也就是说,你直接把这个组件的dll添加到C#的工程中,如果普通的托管代码写的dll一样使用!
既然是COM组件,那么它里面的涉及的数据类型:IItemIdentity 、DataUpdate 、FILETIME 、_IVariant、_IWS_BYTES等会自然在IDL接口里面声明,也就是说,你直接把这个组件的dll添加到C#的工程中,如果普通的托管代码写的dll一样使用!
#2
楼主,你好,"FieldOffset"这个东东也在是网上看C++结构体在转化成C#结构体是要用,本人也不甚了解,甚求解。
本人现在最大的症结在于C#如何调用及使用C++方法具有out二级指针参数,如:
C++:
virtual HRESULT STDMETHODCALLTYPE Read(
/* [in] */ IItemIdentity *IdItems,
/* [in] */ unsigned int ItemsCount,
/* [out] */ DataUpdate **pDataUpdates,
/* [retval][out] */ unsigned int *UpdatesCount) = 0;
C#调用如下:
uint Read( ref MXDATACONSUMERLib._IItemIdentity IdItems, uint ItemsCount, System.IntPtr pDataUpdates)
一级指针在C#里“IItemIdentity ”似乎传递没有多大问题,但二级指针我做了如下处理:
MXDATACONSUMERLib._DataUpdate dataUpdate = new MXDATACONSUMERLib._DataUpdate();
IntPtr dataUpdatePtr = Marshal.AllocHGlobal(Marshal.SizeOf(dataUpdate));
Marshal.StructureToPtr(dataUpdate, dataUpdatePtr, false);
然后再把“dataUpdatePtr”传递给Read(...)方法, 总是出现了错误提示:“The operation did not complete within the time allotted. (Exception from HRESULT: 0x803D0006)”,折腾了我好久,总是不知道如何解决啊,求“大虾”再次指点迷津,跪谢!
本人现在最大的症结在于C#如何调用及使用C++方法具有out二级指针参数,如:
C++:
virtual HRESULT STDMETHODCALLTYPE Read(
/* [in] */ IItemIdentity *IdItems,
/* [in] */ unsigned int ItemsCount,
/* [out] */ DataUpdate **pDataUpdates,
/* [retval][out] */ unsigned int *UpdatesCount) = 0;
C#调用如下:
uint Read( ref MXDATACONSUMERLib._IItemIdentity IdItems, uint ItemsCount, System.IntPtr pDataUpdates)
一级指针在C#里“IItemIdentity ”似乎传递没有多大问题,但二级指针我做了如下处理:
MXDATACONSUMERLib._DataUpdate dataUpdate = new MXDATACONSUMERLib._DataUpdate();
IntPtr dataUpdatePtr = Marshal.AllocHGlobal(Marshal.SizeOf(dataUpdate));
Marshal.StructureToPtr(dataUpdate, dataUpdatePtr, false);
然后再把“dataUpdatePtr”传递给Read(...)方法, 总是出现了错误提示:“The operation did not complete within the time allotted. (Exception from HRESULT: 0x803D0006)”,折腾了我好久,总是不知道如何解决啊,求“大虾”再次指点迷津,跪谢!
#3
你把这com的dll,还有测试它的Demo程序,一起发给我看看:
sdl2002lyx@163.com
sdl2002lyx@163.com
#4
楼主,你好,我们这个Demo需要特殊的运行环境,给了你也运行不起来,谢谢你的好意!
本人现在最大的症结在于C#如何调用及使用C++方法具有out二级指针参数,如何传递的问题,再次谢先了!
本人现在最大的症结在于C#如何调用及使用C++方法具有out二级指针参数,如何传递的问题,再次谢先了!
#5
你发给我,我只是编译测试,不运行,这样说来说去,很久都说不清楚。我写好传入参数,发给你测试,知道吗?
#6
请问 void ** 二级指针如何声明成托管类型?
谢谢
谢谢
#7
http://blog.csdn.net/emailqjc/article/details/6704435
hope it helps
hope it helps
#1
楼主,你明白[FieldOffset(0)]的意思吗?
既然是COM组件,那么它里面的涉及的数据类型:IItemIdentity 、DataUpdate 、FILETIME 、_IVariant、_IWS_BYTES等会自然在IDL接口里面声明,也就是说,你直接把这个组件的dll添加到C#的工程中,如果普通的托管代码写的dll一样使用!
既然是COM组件,那么它里面的涉及的数据类型:IItemIdentity 、DataUpdate 、FILETIME 、_IVariant、_IWS_BYTES等会自然在IDL接口里面声明,也就是说,你直接把这个组件的dll添加到C#的工程中,如果普通的托管代码写的dll一样使用!
#2
楼主,你好,"FieldOffset"这个东东也在是网上看C++结构体在转化成C#结构体是要用,本人也不甚了解,甚求解。
本人现在最大的症结在于C#如何调用及使用C++方法具有out二级指针参数,如:
C++:
virtual HRESULT STDMETHODCALLTYPE Read(
/* [in] */ IItemIdentity *IdItems,
/* [in] */ unsigned int ItemsCount,
/* [out] */ DataUpdate **pDataUpdates,
/* [retval][out] */ unsigned int *UpdatesCount) = 0;
C#调用如下:
uint Read( ref MXDATACONSUMERLib._IItemIdentity IdItems, uint ItemsCount, System.IntPtr pDataUpdates)
一级指针在C#里“IItemIdentity ”似乎传递没有多大问题,但二级指针我做了如下处理:
MXDATACONSUMERLib._DataUpdate dataUpdate = new MXDATACONSUMERLib._DataUpdate();
IntPtr dataUpdatePtr = Marshal.AllocHGlobal(Marshal.SizeOf(dataUpdate));
Marshal.StructureToPtr(dataUpdate, dataUpdatePtr, false);
然后再把“dataUpdatePtr”传递给Read(...)方法, 总是出现了错误提示:“The operation did not complete within the time allotted. (Exception from HRESULT: 0x803D0006)”,折腾了我好久,总是不知道如何解决啊,求“大虾”再次指点迷津,跪谢!
本人现在最大的症结在于C#如何调用及使用C++方法具有out二级指针参数,如:
C++:
virtual HRESULT STDMETHODCALLTYPE Read(
/* [in] */ IItemIdentity *IdItems,
/* [in] */ unsigned int ItemsCount,
/* [out] */ DataUpdate **pDataUpdates,
/* [retval][out] */ unsigned int *UpdatesCount) = 0;
C#调用如下:
uint Read( ref MXDATACONSUMERLib._IItemIdentity IdItems, uint ItemsCount, System.IntPtr pDataUpdates)
一级指针在C#里“IItemIdentity ”似乎传递没有多大问题,但二级指针我做了如下处理:
MXDATACONSUMERLib._DataUpdate dataUpdate = new MXDATACONSUMERLib._DataUpdate();
IntPtr dataUpdatePtr = Marshal.AllocHGlobal(Marshal.SizeOf(dataUpdate));
Marshal.StructureToPtr(dataUpdate, dataUpdatePtr, false);
然后再把“dataUpdatePtr”传递给Read(...)方法, 总是出现了错误提示:“The operation did not complete within the time allotted. (Exception from HRESULT: 0x803D0006)”,折腾了我好久,总是不知道如何解决啊,求“大虾”再次指点迷津,跪谢!
#3
你把这com的dll,还有测试它的Demo程序,一起发给我看看:
sdl2002lyx@163.com
sdl2002lyx@163.com
#4
楼主,你好,我们这个Demo需要特殊的运行环境,给了你也运行不起来,谢谢你的好意!
本人现在最大的症结在于C#如何调用及使用C++方法具有out二级指针参数,如何传递的问题,再次谢先了!
本人现在最大的症结在于C#如何调用及使用C++方法具有out二级指针参数,如何传递的问题,再次谢先了!
#5
你发给我,我只是编译测试,不运行,这样说来说去,很久都说不清楚。我写好传入参数,发给你测试,知道吗?
#6
请问 void ** 二级指针如何声明成托管类型?
谢谢
谢谢
#7
http://blog.csdn.net/emailqjc/article/details/6704435
hope it helps
hope it helps