当然要现在IDL文件中先定义这么一个数据类型 然后在接口定义里使用: typedef [ uuid(D75588D9-ED2D-4FAF-A1F1-4586E3887F92) ] struct tagLineDataStruct { short Year; short Month; short Day; short Hour; short Min; float fOpen; float fClose; float fHigh; float fLow; } LINEDATA;接下来的接口定义中参数定义示例为: [in]short nLen,[in,size_is(nLen)] LINEDATA pArray[ ]
用unsigned char*最好了 ,收到后再强制转化一下,ok!
up! 在VB等解释性语言里效果如何?
<ATL 开发指南>有详细的例子!!
Don't use char*. It is a unsafe way. I suggest you to read some article abut SafeArray.No Chinese IME
在IDL文件中定义数据类型 typedef [ uuid(D75588D9-ED2D-4FAF-A1F1-4586E3887F92) ] struct tagLineDataStruct { short Year; short Month; short Day; short Hour; short Min; float fOpen; float fClose; float fHigh; float fLow; } LINEDATA;接下来的接口定义中参数定义示例为: 当然要现在IDL文件中先定义这么一个数据类型 然后在接口定义里使用: typedef [ uuid(D75588D9-ED2D-4FAF-A1F1-4586E3887F92) ] struct tagLineDataStruct { short Year; short Month; short Day; short Hour; short Min; float fOpen; float fClose; float fHigh; float fLow; } LINEDATA;接下来的接口定义中参数定义为: HRESULT AddLineData([in] long cMax,[in,size_is(cMax)] LINEDATA *psa); 编译通过。测试,在对话框里引用ActiveX控件,生成的控件类找不到AddLineData()方法,但在Active control test container 可以看到该方法。why? 如何解决,我头都大了:(
在VB下也可找到AddLineData()方法
to semir(ATL)typedef [ uuid(D75588D9-ED2D-4FAF-A1F1-4586E3887F92) -?这里的uuid具体是谁的?? ] struct tagLineDataStruct { short Year; short Month; short Day; short Hour; short Min; float fOpen; float fClose; float fHigh; float fLow; } LINEDATA;
typedef [ uuid(AB5526D5-736A-4a3e-BB87-35450C1FC7DF), version(1.0), helpstring("存储K线数据的结构") ] struct tagKLineDataStruct { short Year; short Month; short Day; short Hour; short Min; float fOpen; // 开盘价 float fClose; // 收盘价 float fHigh; // 最高价 float fLow; // 最低价 float fVol; // 成交量 float fAmt; // 成交额 } KLINEDATA;*/
这里的uuid的意义是什么??代表一个结构(calss)吗??-----即是CLSID; ??
以我的理解应是代表一个结构,也有一种作法是不用uuid: typedef struct tagKLineDataStruct { short Year; short Month; short Day; short Hour; short Min; float fOpen; // 开盘价 float fClose; // 收盘价 float fHigh; // 最高价 float fLow; // 最低价 float fVol; // 成交量 float fAmt; // 成交额 } KLINEDATA; 问题还是一样。
to skoog(鸭子) :in]short nLen,[in,size_is(nLen)] LINEDATA pArray[ ]你使用上面的代码正确了吗?我也在做同样的事情, 多多交流。
是否要在IDL定义结构
另外,用结构数组来传递数据,在VB等解释性语言里能用吗,效果如何?
然后在接口定义里使用:
typedef
[
uuid(D75588D9-ED2D-4FAF-A1F1-4586E3887F92)
]
struct tagLineDataStruct
{
short Year;
short Month;
short Day;
short Hour;
short Min;
float fOpen;
float fClose;
float fHigh;
float fLow;
} LINEDATA;接下来的接口定义中参数定义示例为:
[in]short nLen,[in,size_is(nLen)] LINEDATA pArray[ ]
在VB等解释性语言里效果如何?
I suggest you to read some article abut SafeArray.No Chinese IME
typedef
[
uuid(D75588D9-ED2D-4FAF-A1F1-4586E3887F92)
]
struct tagLineDataStruct
{
short Year;
short Month;
short Day;
short Hour;
short Min;
float fOpen;
float fClose;
float fHigh;
float fLow;
} LINEDATA;接下来的接口定义中参数定义示例为:
当然要现在IDL文件中先定义这么一个数据类型
然后在接口定义里使用:
typedef
[
uuid(D75588D9-ED2D-4FAF-A1F1-4586E3887F92)
]
struct tagLineDataStruct
{
short Year;
short Month;
short Day;
short Hour;
short Min;
float fOpen;
float fClose;
float fHigh;
float fLow;
} LINEDATA;接下来的接口定义中参数定义为:
HRESULT AddLineData([in] long cMax,[in,size_is(cMax)] LINEDATA *psa);
编译通过。测试,在对话框里引用ActiveX控件,生成的控件类找不到AddLineData()方法,但在Active control test container 可以看到该方法。why? 如何解决,我头都大了:(
[
uuid(D75588D9-ED2D-4FAF-A1F1-4586E3887F92) -?这里的uuid具体是谁的??
]
struct tagLineDataStruct
{
short Year;
short Month;
short Day;
short Hour;
short Min;
float fOpen;
float fClose;
float fHigh;
float fLow;
} LINEDATA;
[
uuid(AB5526D5-736A-4a3e-BB87-35450C1FC7DF),
version(1.0),
helpstring("存储K线数据的结构")
]
struct tagKLineDataStruct
{
short Year;
short Month;
short Day;
short Hour;
short Min;
float fOpen; // 开盘价
float fClose; // 收盘价
float fHigh; // 最高价
float fLow; // 最低价
float fVol; // 成交量
float fAmt; // 成交额
} KLINEDATA;*/
typedef struct tagKLineDataStruct
{
short Year;
short Month;
short Day;
short Hour;
short Min;
float fOpen; // 开盘价
float fClose; // 收盘价
float fHigh; // 最高价
float fLow; // 最低价
float fVol; // 成交量
float fAmt; // 成交额
} KLINEDATA;
问题还是一样。
多多交流。
(作者:王廷正)在RPC的应用里,经常在接口方法中使用结构类型,COM的方法中也可以传递结构类型。就用一个实验简单测试一下在COM方法中传递结构类型。用ATL向导建立一个名字为structsmp的工程,加入一个简单对象MyTest继承接口名为ITestStruct。.
在工程中加入一个文件mytypes.idl,在里面定义一个结构UserInfo如下:
typedef struct
{
long no;
unsigned char name[255];
BSTR address;
}UserInfo;在structsmp.idl的文件头部加入import “mytypes.idl”1. 加入第一个方法GetUserInfo
HRESULT GetUserInfo([out,retval] UserInfo *pUserInfo);
方法的实现如下:
STDMETHODIMP CMyTest::GetUserInfo(UserInfo *pUserInfo)
{
pUserInfo->no=100;
memcpy(pUserInfo->name,"Mona Lisa",10);
pUserInfo->address=SysAllocString(L"Italy");
return S_OK;
}下面用VB程序作为客户端来测试这个方法:新建一个VB的工程,引用此组件。定义组件对象:
Dim obj As New STRUCTSMPLib.MyTest下面调用方法如下:
Dim ui As userinfo
ui = obj.GetUserInfo()
MsgBox ui.no
MsgBox StrConv(ui.Name, vbUnicode)
MsgBox ui.address运行的结果符合了我们的期望,这个实验已经踏出坚实的第一步了。2.下面在组件里添加第二个方法:
HRESULT SetUserInfo([in] UserInfo *pUserInfo);STDMETHODIMP CMyTest::SetUserInfo(UserInfo *pUserInfo)
{
USES_CONVERSION;
char info[255];
WriteLog("begin SetUserInfo function");
sprintf(info,"pUserInfo->no is:%d,pUserInfo->name is:%s,pUserInfo->address is:%s",pUserInfo->no,pUserInfo->name,OLE2T(pUserInfo->address));
WriteLog(info);
return S_OK;
}WriteLog函数是一个把信息写进文件的函数。在VB的客户程序里:Dim ui As userinfo
ui.no = 101
ui.Name(0) = Asc("h")
ui.Name(1) = Asc("e")
ui.Name(2) = Asc("l")
ui.Name(3) = Asc("l")
ui.Name(4) = Asc("o")
ui.address = "world"
obj.SetUserInfo ui查看最终的结果,又是正确的,这次的结果让人信心倍增。3.从现在来看对单个结构在接口方法里传递没有任何的问题,下面就是该考虑结构数组的时候了,一口气添加两个方法,请看:在接口里添加两个方法,传递结构数组,并且在方法的实现里写上测试的代码。
HRESULT SetUserInfoArray([in] long cMax,[in,size_is(cMax)] UserInfo *pUserInfo);
HRESULT GetUserInfoArray([in] long cMax,[out,size_is(cMax)] UserInfo *pUserInfo);STDMETHODIMP CMyTest::SetUserInfoArray(long cMax, UserInfo *pUserInfo)
{
USES_CONVERSION;
char info[255];
WriteLog("begin SetUserInfoArray function");
for(int i=0;i<cMax;i++)
{
sprintf(info,"%d:pUserInfo->no is:%d,pUserInfo->name is:%s,pUserInfo->address is:%s",i+1,pUserInfo->no,pUserInfo->name,OLE2T(pUserInfo->address));
WriteLog(info);
pUserInfo++;
}
return S_OK;
}STDMETHODIMP CMyTest::GetUserInfoArray(long cMax, UserInfo *pUserInfo)
{
for(int i=0;i<cMax;i++)
{
pUserInfo->no=100;
memcpy(pUserInfo->name,"Mona Lisa",10);
pUserInfo->address=SysAllocString(L"Italy");
pUserInfo++;
}
return S_OK;
}现在在VB的客户程序里加上测试这两个方法的代码:Dim ui(9) As userinfo
obj.GetUserInfoArray 10, ui(0)
For i = 0 To 9
Debug.Print ui(i).no
Debug.Print StrConv(ui(i).Name, vbUnicode)
Debug.Print ui(i).address
Next和Dim ui(9) As userinfo
For i = 0 To 9
ui(i).no = 101
ui(i).Name(0) = Asc("h")
ui(i).Name(1) = Asc("e")
ui(i).Name(2) = Asc("l")
ui(i).Name(3) = Asc("l")
ui(i).Name(4) = Asc("o")
ui(i).address = "world"
Next
obj.SetUserInfoArray 10, ui(0)ACTION的结果可以说让我们欣喜若狂,结构类型在接口里畅通无阻。4.远程调用
狂喜过后我们又要进行下一步的实验,这一次针对的是结构类型的方法在远程调用中的特性。在这里我们使用系统提供的代理dllhost.exe和标准调度,客户程序是一个控制台程序。这一次结构类型又不负众望顺利过关,表现的非常完美。到此实验就OVER了,以后可以放心大胆的在COM的方法里使用结构类型啦。
我作的时候也是参照了上面这篇文章的,还有搜索本栏目以往的一些文章。
我不知道他们作的时候是否也有与我一样的问题。
{
long no;
unsigned char name[255];
BSTR address;
}UserInfo;
我把结构体定义为:
typedef struct _PARAMETER
{
boolean bIn; //flag : 0--in, !0--out
VARIANT value; //value of the parameter
} PARAMETER;
结果vb不能用这个结构体。
Variable uses a automation type not supported in Visual Basic (Error 458)