MSDN上有一个例子,如下。 我试过,通过(用VB或VC调用),VBSCRIPT不行 这个例子传入一个long型数组,第二个参数是求和的值。 另外,我发现,如果组件是进程外的,而要回传数组的话,数组参数类型必须是[in,out]另外 ynlg(ynlg)的方法也是对的。Sample:This sample calculates the sum of long integers in a SAFEARRAY using a function in an ActiveX DLL created with the ActiveX Template Library (ATL) wizard. In Visual C create an ATL DLL using the ATL COM AppWizard. Name it MyAtlDll. From the Insert menu, select New ATL Object. Highlight Objects in the category list and select Simple Object in the Objects list. Click Next. Type in MyClass in the Short Name field, and then click the Attributes tab. Check the following options and then click OK: Threading Model: Apartment Interface: Dual Aggregation: Yes On the ClassView pane in the workspace, right-click IMyClass and select Add Method. Type AddLongs in the Method Name text box and type the following in the Parameters text box: 4. [in,out] SAFEARRAY (long) *psaMyArray, [in,out] long *plSum Note for Visual C version 6.0: If you are using Visual C version 6.0 you may receive the following error message: Unable to create the function because the header or the implementation file could not be found. This is a known issue in the wizard of Visual C version 6.0. You can by pass this error by manually changing the parameters for the AddLongs method in the header, source and .idl files as explained here: In the Parameters list type in: [in,out] long *psaMyArray, [in,out] long *plSum On the FileView tab in the workspace, expand MyAtlDll files. Under the header files double-click the MyClass.h header file. At the very end of this file you will find the declaration of your method: STDMETHOD(AddLongs)(/*[in,out]*/ long *psaMyArray, /*[in,out]*/ long *plSum); Change it to the following: STDMETHOD(AddLongs)(/*[in,out]*/ SAFEARRAY **psaMyArray, /*[in,out]*/ long *plSum); Under the Source Files list double-click MyClass.cpp. Here you will find the implementation of your method. Change the following line: STDMETHODIMP CMyClass::AddLongs(long *psaMyArray, long *plSum) to: STDMETHODIMP CMyClass::AddLongs(SAFEARRAY **psaMyArray, long *plSum) Also, under the Source Files list, double-click the .idl file (the only one with an .idl extension) and locate the following line: [id(1), helpstring("method AddLongs")] HRESULT AddLongs([in,out] long *psaMyArray, [in,out] long *plSum); Change it to: [id(1), helpstring("method AddLongs")] HRESULT AddLongs([in,out] SAFEARRAY(long) *psaMyArray, [in,out] long *plSum); Double-click the implementation file, MyClass.cpp, under the Source Files list. In the implementation file add the following code to your function: 2. 3. STDMETHODIMP CMyClass::AddLongs(SAFEARRAY * * psaArray, long * plSum)4. {5. 6. // TODO: Add your implementation code here7. long lElements; // number of elements in the array8. long iCount;9. HRESULT lResult; // return code for OLE functions10. long *pArrayElements; // pointer to the elements of the array11. 12. // initializing the output13. *plSum=0;14. 15. // checking if it is a one-dimensional array16. if ( (*psaArray)->cDims != 1 ) return(E_FAIL);17. 18. // checking if it is an array of longs19. if ( (*psaArray)->cbElements != 4 ) return(E_FAIL);20. 21. // how many elements are there in the array22. lElements=(*psaArray)->rgsabound[0].cElements;23. 24. // locking the array before using its elements25. lResult=SafeArrayLock(*psaArray);26. if(lResult)return(lResult);27. 28. // using the array29. pArrayElements=(long*) (*psaArray)->pvData;30. for (iCount=0; iCount<lElements; iCount++)31. *plSum = *plSum + pArrayElements[iCount];32. 33. // releasing the array34. lResult=SafeArrayUnlock(*psaArray);35. if (lResult) return(lResult);36. 37. return S_OK; } Build the DLL by pressing the F7 key. In Visual Basic, create a new Standard EXE project. Form1 is created by default. Place a command button named Command1 on Form1. Select References from the Project menu and add a reference to the ActiveX DLL created previously (MyAtlDll). Paste the following code into the Click event of Command1: 43. 44. Private Sub Command1_Click()45. Dim MyObj As New MYATLDLLLib.MyClass46. Dim ArrayOfLongs(3) As Long47. Dim lSum As Long48. 49. ArrayOfLongs(0) = 150. ArrayOfLongs(1) = 251. ArrayOfLongs(2) = 352. 53. MyObj.AddLongs ArrayOfLongs, lSum54. MsgBox "Result from ATL dll = " & Str$(lSum) End Sub Press F5 to run your project. Click Command1. You should see a message box that displays the value 6 returned from the AddLongs method.
先贴出部分代码,请大虾帮忙:IDL
结构:
struct SessionInfo
{
BSTR SesisonID; //ID
...
}
接口:
HRESULT GetSessionInfoList([out,retval] SAFEARRAY(struct SessionInfo)* ppSA);在接口实现类中:.h 方法声明STDMETHOD(GetSessionInfoList)(SAFEARRAY ** ppSA);.cpp 方法实现STDMETHODIMP CSessionInterface::GetSessionInfoList(SAFEARRAY ** ppSA)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState()); HRESULT hr = S_OK; long idCount = SessionIDToOb.GetCount();
if(idCount==0) return S_OK;
BSTR bstr;
static const NDIMS = 1;
SAFEARRAY *pSA = NULL;
SAFEARRAYBOUND dimension[NDIMS];
dimension[0].lLbound = 0;
dimension[0].cElements = idCount; pSA = SafeArrayCreate(VT_VOID,NDIMS,dimension);//???类型对不对???
if(pSA==NULL) return E_FAIL; POSITION pos;
CString sKey;
CSession* pSession;
pos = SessionIDToOb.GetStartPosition();
long i=0;
SessionInfo *pSessionInfo = NULL;
while(pos)
{
SessionIDToOb.GetNextAssoc(pos,sKey,(CObject *&)pSession);
pSessionInfo = new SessionInfo;
pSessionInfo->SesisonID=pSession->sSessionID.AllocSysString(); //....
hr = SafeArrayPutElement(pSA,&i,(void *)pSessionInfo);
i++;
}
delete pSessionInfo; if(SUCCEEDED(hr))
*ppSA = pSA;
else
SafeArrayDestroy(pSA);
return S_OK;
}哪位有经验的同志给诊断诊断?
这个不对,safearray不能直接用于自定义结构
时间过去很长了,记不得具体实现了,代码现在也找不到了。不过似乎我当时创建结构数组时不是用VT_VOID,而是用VT_ARRAY ,即数组中的结构不是指针,而是数据实体。结构也不是new的,而是直接定义。
你试试
{
BSTR SesisonID; //ID
...
}
include "list"
using namespace std
list<SessionInfo{> aa;
用ATL的枚举模板CCollectONSTL ()参数太多我记不住
运行不出错,但数据没有完全返回回来
struct SessionInfo
{
BSTR SesisonID; //ID
...
}
struct SessionInfoArray
{
long RecordCount;
SAFEARRAY(struct SessionInfo) lpSessionInfo;
}//给每一个结构体加UUID号//.CPP
hr = LoadRegTypeLib(LIBID_NTVDSOAREPORTCOMLib, 1, 0, GetUserDefaultLCID(), &pTypelib);
_ASSERT(SUCCEEDED(hr) && pTypelib);
hr = pTypelib->GetTypeInfoOfGuid(__uuidof(SessionInfo), &pTypeInfo);
_ASSERT(SUCCEEDED(hr) && pTypeInfo);
hr = GetRecordInfoFromTypeInfo(pTypeInfo, &pRecInfo);
_ASSERT(SUCCEEDED(hr) && pRecInfo);psa = SafeArrayCreateVectorEx(VT_RECORD, 0, lpSessionInfoArray.RecordCount, pRecInfo);
hr = SafeArrayAccessData(psa, (void HUGEP**)&lpSessionInfoArray);//为lpSessionInfoArray->lpSessionInfo->SesisonID赋值SafeArrayUnaccessData(psa);
lpSessionInfoArray->lpSessionInfo = psa;
我试过,通过(用VB或VC调用),VBSCRIPT不行
这个例子传入一个long型数组,第二个参数是求和的值。
另外,我发现,如果组件是进程外的,而要回传数组的话,数组参数类型必须是[in,out]另外 ynlg(ynlg)的方法也是对的。Sample:This sample calculates the sum of long integers in a SAFEARRAY using a function in an ActiveX DLL created with the ActiveX Template Library (ATL) wizard. In Visual C create an ATL DLL using the ATL COM AppWizard. Name it MyAtlDll.
From the Insert menu, select New ATL Object. Highlight Objects in the category list and select Simple Object in the Objects list. Click Next. Type in MyClass in the Short Name field, and then click the Attributes tab. Check the following options and then click OK:
Threading Model: Apartment
Interface: Dual
Aggregation: Yes On the ClassView pane in the workspace, right-click IMyClass and select Add Method. Type AddLongs in the Method Name text box and type the following in the Parameters text box:
4. [in,out] SAFEARRAY (long) *psaMyArray, [in,out] long *plSum Note for Visual C version 6.0: If you are using Visual C version 6.0 you may receive the following error message: Unable to create the function because the header or the implementation file could not be found. This is a known issue in the wizard of Visual C version 6.0. You can by pass this error by manually changing the parameters for the AddLongs method in the header, source and .idl files as explained here: In the Parameters list type in: [in,out] long *psaMyArray, [in,out] long *plSum On the FileView tab in the workspace, expand MyAtlDll files. Under the header files double-click the MyClass.h header file. At the very end of this file you will find the declaration of your method: STDMETHOD(AddLongs)(/*[in,out]*/ long *psaMyArray, /*[in,out]*/ long *plSum); Change it to the following: STDMETHOD(AddLongs)(/*[in,out]*/ SAFEARRAY **psaMyArray, /*[in,out]*/ long *plSum); Under the Source Files list double-click MyClass.cpp. Here you will find the implementation of your method. Change the following line: STDMETHODIMP CMyClass::AddLongs(long *psaMyArray, long *plSum) to: STDMETHODIMP CMyClass::AddLongs(SAFEARRAY **psaMyArray, long *plSum) Also, under the Source Files list, double-click the .idl file (the only one with an .idl extension) and locate the following line: [id(1), helpstring("method AddLongs")] HRESULT AddLongs([in,out] long *psaMyArray, [in,out] long *plSum); Change it to: [id(1), helpstring("method AddLongs")] HRESULT AddLongs([in,out] SAFEARRAY(long) *psaMyArray, [in,out] long *plSum); Double-click the implementation file, MyClass.cpp, under the Source Files list. In the implementation file add the following code to your function:
2. 3. STDMETHODIMP CMyClass::AddLongs(SAFEARRAY * * psaArray, long * plSum)4. {5. 6. // TODO: Add your implementation code here7. long lElements; // number of elements in the array8. long iCount;9. HRESULT lResult; // return code for OLE functions10. long *pArrayElements; // pointer to the elements of the array11. 12. // initializing the output13. *plSum=0;14. 15. // checking if it is a one-dimensional array16. if ( (*psaArray)->cDims != 1 ) return(E_FAIL);17. 18. // checking if it is an array of longs19. if ( (*psaArray)->cbElements != 4 ) return(E_FAIL);20. 21. // how many elements are there in the array22. lElements=(*psaArray)->rgsabound[0].cElements;23. 24. // locking the array before using its elements25. lResult=SafeArrayLock(*psaArray);26. if(lResult)return(lResult);27. 28. // using the array29. pArrayElements=(long*) (*psaArray)->pvData;30. for (iCount=0; iCount<lElements; iCount++)31. *plSum = *plSum + pArrayElements[iCount];32. 33. // releasing the array34. lResult=SafeArrayUnlock(*psaArray);35. if (lResult) return(lResult);36. 37. return S_OK; } Build the DLL by pressing the F7 key.
In Visual Basic, create a new Standard EXE project. Form1 is created by default.
Place a command button named Command1 on Form1.
Select References from the Project menu and add a reference to the ActiveX DLL created previously (MyAtlDll).
Paste the following code into the Click event of Command1:
43. 44. Private Sub Command1_Click()45. Dim MyObj As New MYATLDLLLib.MyClass46. Dim ArrayOfLongs(3) As Long47. Dim lSum As Long48. 49. ArrayOfLongs(0) = 150. ArrayOfLongs(1) = 251. ArrayOfLongs(2) = 352. 53. MyObj.AddLongs ArrayOfLongs, lSum54. MsgBox "Result from ATL dll = " & Str$(lSum) End Sub Press F5 to run your project.
Click Command1. You should see a message box that displays the value 6 returned from the AddLongs method.