大家帮我看看这两个三层问题------Variant参数传递的问题

luhongjun 2001-09-04 03:49:22
加精
如果解决不了我就得换开发工具了---换delphi或者vc.net

下面的问题的运行环境:Windows2000专业版、
BCB5专业版+BCB5ADOUpgrade1.exe+BCB5EntUpdate1.exe
MS SQL SERVER7.0

问题1:客户端执行服务器端方法的问题

服务器端程序:
STDMETHODIMP TDynamicSQLDemoImpl::AAAA(BSTR ABC)
{
__try
{
AnsiString abcd="luhongjun "+AnsiString(ABC);
Application->MessageBox(abcd.c_str(), NULL, MB_OK);
}
__finally
{
return S_OK;
}

}
//----------------------------------------------------------------------------------------
STDMETHODIMP TDynamicSQLDemoImpl::GetAllTables(TVariant* vTables)
{
__try
{
TStringList *tblList=new TStringList();
DynamicSQLDemo->adocDSQL->GetTableNames(tblList, false);
int Bounds[2] = {0,tblList->Count};
vTables=VarArrayCreate(Bounds,1,varVariant);
for (int i=0;i<tblList->Count;i++)
{
//vTables.PutElement(tblList->Strings[i],i); // 编译无法通过,直接定义Variant* vTables可以通过
vTables[i]=tblList->Strings[i];
}
Application->MessageBox("aaaaa","11",MB_OK) ; //测试,如果远程调用,并不执行
delete tblList ;
}
__finally
{
return S_OK;
}

}

客户端程序:
void __fastcall TForm1::AAAAClick(TObject *Sender)
{
//客户程序1
Variant vtblList;
if (!SocketConnection1->Connected)
SocketConnection1->Connected=true;
IDispatch* disp = (IDispatch*)(SocketConnection1->AppServer);
IDynamicSQLDemoDisp DynamicSQLDemo( (IDynamicSQLDemo*)disp);
DynamicSQLDemo.AAAA(WideString("This is a TEST"));
}
//-------------------------------------------------------------
void __fastcall TForm1::GetAllTablesClick(TObject *Sender)
{
//客户程序2
Variant vtblList;
if (!SocketConnection1->Connected)
SocketConnection1->Connected=true;
IDispatch* disp = (IDispatch*)(SocketConnection1->AppServer);
IDynamicSQLDemoDisp DynamicSQLDemo( (IDynamicSQLDemo*)disp);
DynamicSQLDemo.GetAllTables(vtblList);
if (VarIsArray(vtblList))
{
ListBox1->Items->Add("vtblList is Array");
for (int i=VarArrayLowBound(vtblList,1);i<VarArrayHighBound(vtblList,1);i++)
ListBox1->Items->Add(vtblList.GetElement(i));
}
else
ListBox1->Items->Add("vtblList is not Array");

}
问题:
在上面的程序中,“客户程序1”被执行的时候,服务器端正常显示“luhongjun This is a TEST”对对话框。但“客户程序2”被执行的时候服务段没有任何反映既Application->MessageBox("aaaaa","11",MB_OK) ;都不能被执行,在客户端列表框中提示:vtblList is not Array,说明服务器端的GetAllTables根本就没有被执行,但此例子在Delphi5.0下就好用。

请问:这是为什么,此问题已经困绕我好长时间了,是否是BCB5的BUG。


问题2:用ClientDataSet的集合(Aggregates)属性出现的问题。

在我的系统中ClientDataSet的Aggregates属性已经增加了Sum项
在程序中调用ClientDataSet->Aggregates->Items[0]->Value编译出现问题,提示为:Member function Must be Called or its address taken。但在Delphi5中调用正常。
...全文
874 32 打赏 收藏 转发到动态 举报
写回复
用AI写文章
32 条回复
切换为时间正序
请发表友善的回复…
发表回复
luhongjun 2001-09-05
  • 打赏
  • 举报
回复
DynamicSQLDemo就是远程数据模块名称,改掉之后编译无法通过。
猛禽 2001-09-05
  • 打赏
  • 举报
回复
midas\Adhoc换成SocketConnection就错。怪事。

第一个问题中:
Application->MessageBox("aaaaa","11",MB_OK) ; //测试,如果远程调用,并不执行
不执行的原因好像是前面出了异常。原因不明,好像用SocketConnection时,用ADO都会出错。
HEROIN 2001-09-05
  • 打赏
  • 举报
回复
试试

DynamicSQLDemo->adocDSQL->GetTableNames(tblList, false); //问题出在这里,但在两层的情况下,tblList可以添充内容

改为

m_DataModule->adocDSQL->GetTableNames(tblList, false); //问题出在这里,但在两层的情况下,tblList可以添充内容

MarsChen 2001-09-05
  • 打赏
  • 举报
回复
各位大虾,有能指点一下的么?

http://www.csdn.net/expert/topic/272/272423.shtm
请教如何将一个字符串传递给 VARIANT * 的形参?急,一直在线,给出正确答案马上就给分
luhongjun 2001-09-05
  • 打赏
  • 举报
回复
STDMETHODIMP TDynamicSQLDemoImpl::GetAllTables(TVariant* vTables)
{
__try
{
TStringList *tblList=new TStringList();
try
{
tblList->Add("11111111111111");
tblList->Add("22222222222222");
//DynamicSQLDemo->adocDSQL->GetTableNames(tblList, false); //问题出在这里,但在两层的情况下,tblList可以添充内容
int Bounds[2] = {0,tblList->Count};
Variant vTables1=VarArrayCreate(Bounds,1,varVariant);
for (int i=0;i<tblList->Count;i++)
{
vTables1.PutElement(tblList->Strings[i],i);
}
*vTables = Variant(vTables1);
delete tblList ;
}
catch(Exception &e)
{
return E_FAIL;
}
}
__finally
{
return S_OK;
}

}
经过修改上面的服务端程序,在客户端显示了vtblList is Array,1111,22222
但使用DynamicSQLDemo->adocDSQL->GetTableNames(tblList, false);就不行了。
为什么?

猛禽 2001-09-05
  • 打赏
  • 举报
回复
呵呵,我刚要上来告诉你,用m_DataModule呢,我也是今天才发现的。^_^
ppzhao 2001-09-05
  • 打赏
  • 举报
回复
学到不少
luhongjun 2001-09-05
  • 打赏
  • 举报
回复
问题解决了,HEROIN(HEROIN)和agecntao(火鸟) 说的有道理,使用m_DataModule 就可以了。
HEROIN 2001-09-05
  • 打赏
  • 举报
回复
不会吧?

DynamicSQLDemo->adocDSQL->GetTableNames(tblList, false); 编译可通过,但运行会报

AV,是不能这样用的。根本不存在DynamicSQLDemo这个实例

必须通过DataModule访问啊。

m_DataModule 程序中不用定义
火鸟33 2001-09-05
  • 打赏
  • 举报
回复
没问题了把

该结了
alang_xy 2001-09-04
  • 打赏
  • 举报
回复
再看看。
Againstwind 2001-09-04
  • 打赏
  • 举报
回复
盯着看!!!
luhongjun 2001-09-04
  • 打赏
  • 举报
回复
holyfire(^@L@^):对第二个问题的解答是正确的.
老火可以得80分.

ALNG(?)对第一个问题的解决可能是正确的,如果正确可以得180分.其他的同志可以得剩余的分数.
感觉ALNG(?)的方法是正确的.
哈哈,如果解决了真好.


孩皮妞野 2001-09-04
  • 打赏
  • 举报
回复
这是我向你推荐过的<<精通C++Builder ...>>p507页的例子,没有问题。

STDMETHODIMP TTest125ServerImpl::GetDatabaseNames(TVariant* Ret)
{
int i;
TStrings *DBNames;

// ミ﹃皚ㄓBDE┮Τ戈畐戈
DBNames = new TStringList;
try
{
// ノSessionじンㄓ眔ヘ玡BDE┮Τ戈畐戈
m_DataModule->Session1->GetDatabaseNames(DBNames);

// ミ跑计皚倒ㄧ计肚跑计Result
Variant v = VarArrayCreate(OPENARRAY(int, (0,DBNames->Count-1)), varOleStr);

// 程р戈畐戈﹚倒跑计皚
for(i=0;i<DBNames->Count-1;i++)
v.PutElement(WideString(DBNames->Strings[i]), i);

*Ret = Variant(v);
delete DBNames;
}
catch(Exception &e)
{
return Error(e.Message.c_str(), IID_ITest125Server);
}
return S_OK;
};
HEROIN 2001-09-04
  • 打赏
  • 举报
回复
1.

//vTables.PutElement(tblList->Strings[i],i); // 编译无法通过,直接定义Variant* vTables可以通过

TVariant没有PutElement方法
2.

客户端程序有错啊,编译能通过?
服务端需要TVariant* ,而你给了Variant

3.关于TVariant和Variant转换,我以前做过。我试图把TProvider的Data(也就是返回的数据集)直接通过自定义函数返回。在经过来回类型转换(试了x种方法),结果客户端报"不是有效的数据格式"。没办法,最后我只好用Delphi做服务端




测试结果如何?服务端方法有没被调用?
火鸟33 2001-09-04
  • 打赏
  • 举报
回复
http://www.csdn.net/expert/TopicView.asp?id=271548
孩皮妞野 2001-09-04
  • 打赏
  • 举报
回复
估计这两个问题都被Holyfire解决了。 贴一些材料吧

In article <VA.00000060.09412186@nospam.demon.co.uk>,
Daniel James <internet@nospam.demon.co.uk> wrote:
>of ATL and there are some differences. The Microsoft ATL sources won't compile
>unchanged in BCB. To make matters worse, there is at least one fairly serious

Huh? In BCB 5, at least, the ATL 3 headers compiled unchanged when i
put them in two years ago this month.

The problem is that they won't *precompile* unchanged. Since nobody
wants to have to recompile the ATL every time they build, that was a
problem.


>and correct me) COM objects' reference counts being updated incorrectly when
>interfaces are passed as parameters between BCB COM code and non-BCB COM code
>(as you will be doing, as part of your code will still be in VB).

This is true.
This will be fixed in the next release of C++Builder.

说明,发件人估计是BCB开发组中负责ActiveX技术这一块的,E-Mail 地址aphrael@minasanor.borland.com 。 我想他的话有相当的可信度。



Robert, it's true, to the best of my recollection that ATL as is will
not compile without massaging - the trick is to compile it sans VCL. You
may recall I wrote an article for the C++ Builder Developer's Journal
that showed how to create pure ATL servers in BCB. That's when I
encountered compilation problems. But I have to admit they were due to
the buggy VC-- C++ compliance.

发件人Alex Bakaev, TeamB成员, 他说问题出在VC不遵循C++标准。 Microsoft就是牛,
不跟他一样错也是一种错!

holyfire 2001-09-04
  • 打赏
  • 举报
回复
第二问题

ClientDataSet->Aggregates->Items[0]->Value();
Value是个函数

在Delphi里无参数的函数不需要()的。
luhongjun 2001-09-04
  • 打赏
  • 举报
回复
谢谢大家,我先下了,测试一下。
火鸟33 2001-09-04
  • 打赏
  • 举报
回复
你看看他的例子 midas\Adhoc目录下

它的跟你的类似啊

你看看
加载更多回复(12)

13,825

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder相关内容讨论区
社区管理员
  • 基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧