一个分布式的小数据库程序(DCOM) DCOM服务程序导出三个方法,1个成功2个失败,不知道为什么?

jxw1987628 2008-02-26 02:46:56
#include <vcl.h>
#pragma hdrstop

#include "MULTICOMPANYDATAIMPL.H"

#if !defined(__PRAGMA_SMART_INIT_DEFINED)
#define __PRAGMA_SMART_INIT_DEFINED
#pragma package(smart_init)
#endif

#pragma resource "*.dfm"


/////////////////////////////////////////////////////////////////////////////
// Global instance of TMultiCompanyDataImpl
/////////////////////////////////////////////////////////////////////////////
TMultiCompanyData *MultiCompanyData;这个是一个REmote数据模块


/////////////////////////////////////////////////////////////////////////////
// TMultiCompanyData::TMultiCompanyData
/////////////////////////////////////////////////////////////////////////////
__fastcall TMultiCompanyData::TMultiCompanyData(TComponent* Owner) : TCRemoteDataModule(Owner)
{
}





STDMETHODIMP TMultiCompanyDataImpl::InsertDataRecord(BSTR Name,
BSTR Captial, BSTR Continent, BSTR Area, BSTR Population)
{

try
{

Form1->InsertDataRecord(Name,Captial,Continent,Area,Population);
}
catch(Exception &E)
{
return Error(E.Message.c_str(),IID_IMultiCompanyData );
}
return S_OK;
}


STDMETHODIMP TMultiCompanyDataImpl::RefreshDataRecord()
{
try
{
Form1->RefreshDataRecord();
}
catch(Exception &E)
{
return Error(E.Message.c_str(),IID_IMultiCompanyData );
}
return S_OK;
}


STDMETHODIMP TMultiCompanyDataImpl::TestCall(BSTR* AName)
{
try
{
AnsiString S="hello world";
*AName =WideString(S);
}
catch(Exception &E)
{
return Error(E.Message.c_str(),IID_IMultiCompanyData );
}
return S_OK;
}

STDMETHODIMP TMultiCompanyDataImpl::GetFirstField(BSTR* Name)
{
try
{
if(!MultiCompanyData->Table1->Active)
MultiCompanyData->Table1->Open();
*Name =WideString(MultiCompanyData->Table1->Fields->Fields[0]->FieldName);
}
catch(Exception &E)
{
return Error(E.Message.c_str(),IID_IMultiCompanyData );
}
return S_OK;
}
各个函数的具体实现如下:
/////////////////////////////////////////////////////////////////////////////////////////
void __fastcall TForm1::RefreshDataRecord()
{
MultiCompanyData->Table1->Close();
MultiCompanyData->Table1->Open();

}

void __fastcall TForm1::InsertDataRecord(AnsiString Name,AnsiString Captial,
AnsiString Area, AnsiString Continent, AnsiString Population)
{

try
{
MultiCompanyData->Table1->Insert();
MultiCompanyData->Table1->Fields->Fields[0]->Value=Name;
MultiCompanyData->Table1->Fields->Fields[0]->Value=Captial;
MultiCompanyData->Table1->Fields->Fields[0]->Value=Area;
MultiCompanyData->Table1->Fields->Fields[0]->Value=Continent;
MultiCompanyData->Table1->Fields->Fields[0]->Value=Population;
MultiCompanyData->Table1->Post();
RefreshDataRecord();
ShowMessage("SUCCEED IN INSERTING RECORD !");
}
catch(Exception &E)
{
ShowMessage(E.Message);
}

}

以下为客户程序的调用导出方法的代码,但只有Testcall可以成功,GetFirstField返回空字串。。最后那个发EAcessAoscction消息框

////////////////////////////////////////////////////////////////////////////////////////////
__fastcall TForm2::TForm2(TComponent* Owner)
: TForm(Owner)
{
CoInitialize(NULL);
}
//---------------------------------------------------------------------------

void __fastcall TForm2::Button1Click(TObject *Sender)
{
WideString S;
WideString S2;
TCOMIMultiCompanyData ComServer=CoMultiCompanyData::Create();
//测试服务器连接
ComServer->TestCall(&S);
ShowMessage(S);
//测试方法1

ComServer->GetFirstField(&S2);
ShowMessage(S2);
//测试方法2
//ComServer->InsertDataRecord(WideString(Edit1->Text),WideString(Edit2->Text),WideString(Edit3->Text),WideString(Edit4->Text),WideString(Edit5->Text));


}
//---------------------------------------------------------------------------

以下为客户程序的调用导出方法的代码,但只有Testcall可以成功,GetFirstField返回空字串。。最后那个发EAcessAoscction消息框

不知道,为什么包含数据模块的代码,或者包含窗体里面的函数的方法导出调用就不成功,请高手解决,谢谢。。。。。。。

QQ:462511021
Email:jxw1987628@163.com


...全文
96 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
jxw1987628 2008-03-01
  • 打赏
  • 举报
回复
另外你说的那个WideString的我问题,我没有Detach也可以的。

有的时候是需要Detach的,这个我知道。。


加我QQ: 462511021
jxw1987628 2008-03-01
  • 打赏
  • 举报
回复
谢谢毛毛。确实是MultiCompanyData这个实例VCL并不自动帮我们创建。。。

以前我一直以为他会自动创建一个实例。看来并不是这样的。。。

这个问题一直萦绕我好几天了,谢谢了,分马上给。。。

对了。你的qq是多少啊,有没有加群19882783(BCB程序员联盟)
Waiting4you 2008-03-01
  • 打赏
  • 举报
回复
奇怪,怎么我回的源码内容换成其它的了?

我只有msn, 而且一个月也不用一次:-P

mao_yj@msn.com
Waiting4you 2008-02-28
  • 打赏
  • 举报
回复
用VCL源码加强一下我的论点,呵呵
namespace System
{
// NOTE: WideString uses BSTRs as its underlying implementation (i.e. SysAlloc/FreeString etc.)
//
class RTL_DELPHIRETURN WideString
{
// ...
BSTR __fastcall c_bstr() const { return Data; }
operator BSTR() const { return Data; }
// ...
BSTR __fastcall Detach();
// ...
private:
wchar_t *Data;
};
};

BSTR __fastcall WideString::Detach()
{
BSTR bstr = Data;
Data = 0;
return bstr;
}
Waiting4you 2008-02-28
  • 打赏
  • 举报
回复
我用你的代码测试了一下,说实话我还没用Remote Module实战过呢,加上创建适合你代码的数据库,花了不少时间:-P

测试发现MultiCompanyData这个实例VCL并不自动帮我们创建。于是在服务端加入下面这个就OK了:

__fastcall TForm1::TForm1 ( TComponent* Owner )
: TForm ( Owner )
{
MultiCompanyData = new TMultiCompanyData(this);
}


另外关于WideString的论述我还是坚持我的看法,你应该Detach。
jxw1987628 2008-02-28
  • 打赏
  • 举报
回复
按照你的改了后,依然只有第一个方法调用成功,也就是TestCall调用成功。。。。。。

我觉得是不是代码里包含窗体Form里的数据,所以导出来时,客户程序再调用就访问不到啊 。。。。

单独调用GetFirstField也是一样的结果,不成功,返回为空串。。。


期待解决,谢谢。。。

08-02-28
jxw1987628 2008-02-28
  • 打赏
  • 举报
回复
TestCall调用是正常的啊
STDMETHODIMP TMultiCompanyDataImpl::TestCall(BSTR* AName)
{
try
{
AnsiString S="hello world";
*AName =WideString(S);
}
catch(Exception &E)
{
return Error(E.Message.c_str(),IID_IMultiCompanyData );
}
return S_OK;
}
/////////////////////////////////////////////
上面这个函数的运行正常的啊,可以 得到正确的结果,
但下两个方法得不到正确的结果。。。。。。
Waiting4you 2008-02-27
  • 打赏
  • 举报
回复
你返回BSTR时不能这么写: *AName = WideString ( S );

因为WideString管理了这个BSTR, 等退出函数时这块数据已经无效了,你能看到有效只是它还没被其它数据覆盖而已。

改成这样:
*AName = WideString(S).Detach(); 让WideString不再管理AName指向的BSTR。

703

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder ActiveX/COM/DCOM
社区管理员
  • ActiveX/COM/DCOM社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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