从ActiveX控件向JavaScript传递数组似乎不是一件容易的事,因为JavaScript好像不能接受从ActiveX控件传来的引用参数,所以实际上我并没有找到直接传递的方案(如果有朋友找到了,欢迎留言),而是绕了个弯,将数组格式化成字符串传了出去。看到这里,可能很多朋友已经完全明白我的做法了。对于不太熟悉COM编程的朋友,可以看看下面的具体步骤:
(1)为ActiveX控件增加传递数组的接口函数(方法),该函数的返回参数为[out, retval] BSTR* fvector。因为BSTR和JavaScript中的字符串都是Unicode编码的,所以可以无需转换直接传递。
(2)函数实现示例
#include <stdio.h>
//将数组格式化为空格相隔的字符串
STDMETHODIMP CMyClass::CalFeatureVector(BSTR *fvector)
{
double dFv[50];
int dim = 50;
//allocate a buffer large enough to hold the string converted from the array
wchar_t vecbuf[1000];
wcscpy(vecbuf, L"");
wchar_t numbuf[20];
for(int i=0; i<dim-1; i++) //concat the double number with a blank
{
swprintf(numbuf, L"%.8f ", dFv[i]); //见注释1
wcscat(vecbuf, numbuf);
}
swprintf(numbuf, L"%.8f", dFv[dim-1]); //the last one doesn't need to append a blank
wcscat(vecbuf, numbuf);
*fvector = SysAllocString(vecbuf); //return the string of the vector //见注释2
return S_OK;
}
注释:
1.需引入头文件<stdio.h>,若出现链接错误,则可在VC6.0的工程设置中选择C/C++选项,将预处理程序定义
中的_MIN_CRT去掉。该宏的作用是最小化引入CRT库,减小控件大小,但会使有些C库函数用不了。
2.COM中分配字符串的常用方法是SysAllocString,勿使用fvector = new wchar_t[1000],这样最多只能申请
长度为490的字符串,超过490就会出错。另外虽然没有用SysFreeString释放字符串,但经测试上百万次用上述
方式将ActiveX控件中的字符串传递给JavaScript,并没有发现内存增加,估计是JavaScript中的内存管理机制
对字符串进行了自动回收。