ATL控件返回值不能返回出去是基于什么com原理呢,该怎么解决
ATL控件返回值不能返回出去是基于什么com原理呢
遇到一个很奇怪的问题,虽然自己乱打乱撞已经解决了,但是不明白基于的原理是什么,所以拿出来求教一下,大家来讨论讨论
STDMETHODIMP Cytiicrj::say(BSTR pic, VARIANT* ret)
{
// TODO: 在此添加实现代码
char* get = NULL;
char show[200] = {'\0'};
int i_length = 0;
BSTR bstr_result = NULL;
char pcval[500] = {'\0'};
int i_point = 0;
WERROR cerr; //流程监控类
God C_god;
memset(bstr_val, '\0', 400);
char* file=_com_util::ConvertBSTRToString(pic); //pic为图片路径,要用delete[] file来释放
if(NULL == file)
{
cerr.WriteLog("获取的图片路径字符串为空");
return S_OK;
}
get = C_god.say(file); //获取到结果,这里get是指向在C_god.say里用malloc分配的内存
if(NULL == get)
{
cerr.WriteLog("获取识别结果失败");
return S_OK;
}
else
{
cerr.WriteLog("得到返回值");
}
strcpy(pcval, get);
free(get); //将取得结果置于pcval变量中后释放
get = NULL;
//重点是这里,此方法为方法一
CComBSTR C_convert(pcval);//把char*型转换成BSTR型
ret->vt = VT_BSTR;
ret->bstrVal = C_convert.Copy();
//曾采用的失败的方法二
//bstr_result = _com_util::ConvertStringToBSTR(pcval);
//ret->vt = VT_BSTR;
//ret->bstrVal = bstr_result;
//当然在得到返回值后会调用其他接口函数使用SysFreeString(bstr_result);来释放内存
delete[] file;
file = NULL;
C_convert.Empty();
this->_AtlFinalRelease();
cerr.WriteLog("释放say方法成功"); //打印结果
return S_OK;
}
这里我的疑问是这个控件使用简单的测试网页进行测试的时候是可以用方法一即ConvertStringToBSTR转换函数来转换得到返回值的,测试网页的代码如下。
但置于项目中的时候,调用控件的接口函数Cytiicrj.say与测试网页如出一辙,但是返回值确是空。
如果用CComBSTR类来作char*类型到BSTR类型的转换,则能解决问题,即测试网页和项目工程的网页均可得到返回值。
<<HTML>
<HEAD>
<TITLE>New Page</TITLE>
<OBJECT id=Cytiicrj align="CENTER" WIDTH=0 HEIGHT=0 codeBase="test.CAB#version=9,0,0,1" classid="CLSID:CD65780A-D4D6-4B2A-80AC-429F47E0EDB5"></OBJECT>
<script language="javascript">
function doTest()
{
alert("开始识别图片");
var sum;
var i;
var begintime = new Date();
// var begintime = nowtime.getTime();
for(i = 0; i < 5; i++)
{
try
{
sum = Cytiicrj.say("C:\\Documents and Settings\\Administrator\\桌面\\申请表jpg\\标准卡\\残缺.jpg");
var str = sum.substr(0,8);
if(str != "00AZ1101")
{
alert("error");
alert(sum);
}
}
catch (e)
{
alert(e.message);
alert(e.description)
alert(e.number)
alert(e.name)
alert("加载控件失败!===");
return;
}
}
// var endtime = nowtime.getTime();
var endtime = new Date();
var resulttime = (endtime.getTime() - begintime.getTime())/1000;
alert(resulttime);
alert(i);
}
</script>
</HEAD>
<BODY>
<input type="button" value="renjie" id="btnOK" onclick="doTest();"></input>
</BODY>
</HTML>
------解决方案--------------------
你说的这个和COM原理没有关系
char*不能返回,是因为Javascript不支持char*类型字符串,仅能识别BSTR类型字符串
------解决方案--------------------
方法二
//当然在得到返回值后会调用其他接口函数使用SysFreeString(bstr_result);来释放内存
这个你不需要释放了,调用者javascript会替你释放。
VARIANT* ret应该为[out,retval]
遇到一个很奇怪的问题,虽然自己乱打乱撞已经解决了,但是不明白基于的原理是什么,所以拿出来求教一下,大家来讨论讨论
STDMETHODIMP Cytiicrj::say(BSTR pic, VARIANT* ret)
{
// TODO: 在此添加实现代码
char* get = NULL;
char show[200] = {'\0'};
int i_length = 0;
BSTR bstr_result = NULL;
char pcval[500] = {'\0'};
int i_point = 0;
WERROR cerr; //流程监控类
God C_god;
memset(bstr_val, '\0', 400);
char* file=_com_util::ConvertBSTRToString(pic); //pic为图片路径,要用delete[] file来释放
if(NULL == file)
{
cerr.WriteLog("获取的图片路径字符串为空");
return S_OK;
}
get = C_god.say(file); //获取到结果,这里get是指向在C_god.say里用malloc分配的内存
if(NULL == get)
{
cerr.WriteLog("获取识别结果失败");
return S_OK;
}
else
{
cerr.WriteLog("得到返回值");
}
strcpy(pcval, get);
free(get); //将取得结果置于pcval变量中后释放
get = NULL;
//重点是这里,此方法为方法一
CComBSTR C_convert(pcval);//把char*型转换成BSTR型
ret->vt = VT_BSTR;
ret->bstrVal = C_convert.Copy();
//曾采用的失败的方法二
//bstr_result = _com_util::ConvertStringToBSTR(pcval);
//ret->vt = VT_BSTR;
//ret->bstrVal = bstr_result;
//当然在得到返回值后会调用其他接口函数使用SysFreeString(bstr_result);来释放内存
delete[] file;
file = NULL;
C_convert.Empty();
this->_AtlFinalRelease();
cerr.WriteLog("释放say方法成功"); //打印结果
return S_OK;
}
这里我的疑问是这个控件使用简单的测试网页进行测试的时候是可以用方法一即ConvertStringToBSTR转换函数来转换得到返回值的,测试网页的代码如下。
但置于项目中的时候,调用控件的接口函数Cytiicrj.say与测试网页如出一辙,但是返回值确是空。
如果用CComBSTR类来作char*类型到BSTR类型的转换,则能解决问题,即测试网页和项目工程的网页均可得到返回值。
<<HTML>
<HEAD>
<TITLE>New Page</TITLE>
<OBJECT id=Cytiicrj align="CENTER" WIDTH=0 HEIGHT=0 codeBase="test.CAB#version=9,0,0,1" classid="CLSID:CD65780A-D4D6-4B2A-80AC-429F47E0EDB5"></OBJECT>
<script language="javascript">
function doTest()
{
alert("开始识别图片");
var sum;
var i;
var begintime = new Date();
// var begintime = nowtime.getTime();
for(i = 0; i < 5; i++)
{
try
{
sum = Cytiicrj.say("C:\\Documents and Settings\\Administrator\\桌面\\申请表jpg\\标准卡\\残缺.jpg");
var str = sum.substr(0,8);
if(str != "00AZ1101")
{
alert("error");
alert(sum);
}
}
catch (e)
{
alert(e.message);
alert(e.description)
alert(e.number)
alert(e.name)
alert("加载控件失败!===");
return;
}
}
// var endtime = nowtime.getTime();
var endtime = new Date();
var resulttime = (endtime.getTime() - begintime.getTime())/1000;
alert(resulttime);
alert(i);
}
</script>
</HEAD>
<BODY>
<input type="button" value="renjie" id="btnOK" onclick="doTest();"></input>
</BODY>
</HTML>
------解决方案--------------------
你说的这个和COM原理没有关系
char*不能返回,是因为Javascript不支持char*类型字符串,仅能识别BSTR类型字符串
------解决方案--------------------
方法二
//当然在得到返回值后会调用其他接口函数使用SysFreeString(bstr_result);来释放内存
这个你不需要释放了,调用者javascript会替你释放。
VARIANT* ret应该为[out,retval]