BCB如何使用MQSERIES的ACTIVEX组件?
我需要在BCB项目里使用MQSERIES通信。经过几天的研究证明了MQ提供的C++ LIB库是VC格式的,不能被BCB直接使用。尝试用MQ的ACTIVEX控件。在BCB里用“PROJECT|IMPORT TYPE LIBARAY”导入“MQAX200.DLL”,创建了MQSession,MQQueue,MQQueueManager等控件。写了以下测试代码:
//==================================================================================
//Unit1.h:
TMQSession *MQSession1;
TMQQueueManager *MQQueueManager1;
//Unit1.cpp:
TOLEBOOL olebool;
AnsiString as;
LPDISPATCH lpDisp;
BSTR bstr;
MQSession=TMQSession(this);
/*-------------------------------
//----用法1:先创建QueueManager对象再连接,编译通过,运行时始终连不上。----
MQQueueManager1=new TMQQueueManager(this);
MQQueueManager1->set_name(WideString("")); //连接默认队列管理器
MQQueueManager1->Connect();
if(MQQueueManager1->IsConnected==TRUE)
ShowMessage("QM connected");
else
ShowMessage("QM none connected:"+AnsiString(MQQueueManager1->CompletionCode)+":"+
AnsiString(MQQueueManager1->ReasonCode)+":"+AnsiString(MQQueueManager1->ReasonName));
----------------------------------*/
//----用法2:用IBM提供的关于VB的范例,使用AccessQueueManager方法建立到QueueManager的连接,编译通过,在访问MQQueueManager1的任意属性或方法时报“AccessViolation”
try{
MQQueueManager1=(TMQQueueManager *)MQSession1->AccessQueueManager(WideString(""));
ShowMessage("CompletionCode="+AnsiString(MQSession1->CompletionCode)+","+
"ReasonCode="+AnsiString(MQSession1->ReasonCode)+","+
"ReasonName="+AnsiString(MQSession1->ReasonName));
//ReasonName为MQRC_NONE,没有任何错误码
if(MQQueueManager1)
{
as=AnsiString(MQQueueManager1->name); //运行到此处,无论访问什么属性或方法,都报“AccessViolation”错误
ShowMessage("QueueManager->ConnectionStatus="+as);
MQQueueInput=(TMQQueue *)MQQueueManager1->AccessQueue(WideString("QUEUE_INPUT"),MQOO_INPUT_SHARED);
MQQueueOutput=(TMQQueue *)MQQueueManager1->AccessQueue(WideString("QUEUE_OUTPUT"),MQOO_OUTPUT);
}
else
ShowMessage("QueryInterface()failed");
}
catch(Exception &E)
{
ShowMessage("You got an exception:"+E.Message);
}
//=============================================================================
我另外还尝试了用IDispatch接口的QueryInterface方法获得MQQueueManager1指针:
lpDisp=MQSession1->AccessQueueManager(WideString(EditQueueManager->Text));
lpDisp->QueryInterface(DIID_IMQQueueManager500,(void **)&MQQueueManager1);
通过查看MQAX200_OCX.H,得知TMQQueueManager的缺省Interface正是IMQQueueManager500
而且通过调试,证明上述两种方法获得的指针地址都是一样的。BCB在Inspect里都可以正确解析出TMQQueueManager的结构
PS.经过跟踪,找到了AccessViolation的代码,在BCB导入MQAX200时自动生成的MQAX200_OCX.CPP:
IMQQueueManager500Ptr& TMQQueueManager::GetDefaultInterface()
{
if (!m_DefaultIntf)
Connect(); //停留在这一行!!!
return m_DefaultIntf;
}
我就想不通了,为什么方法1会连不上队列管理器,方法2会报AccessViolation?
顺便说一下环境:
OS:WinXP
MQ: IBM MQSERIES V5.3.0.11
BORLAND C++ BUILDER 6.0
本机安装了MQ服务器和客户端,建立了一个缺省队列管理器。用另一个同事用VC写的MQ客户端可以正确连上我本机的队列并收发消息。
请问我的代码还有什么问题?是否需要设置什么环境变量?
我读过了IBM的《MQ编程模式》,《MQ使用COM部件编程》等文档,唯独没有写C++如何使用COM部件。
请高手们指点。