Author |
Message
|
boutwater |
Posted: Mon Sep 12, 2005 8:27 am Post subject: Lib files with Borland C++ builder |
|
|
Novice
Joined: 12 Sep 2005 Posts: 12
|
I have two questions:
1) I want to be able to use MQ series client libraries with Borland C++ Builder 6.0. I noticed one posting here that said that if I used IMPDEF on the library in question, then replaced all Foo @1 with _Foo=Foo. The problem is, there are so many places in there with the @ symbol, i don't know which ones to change. Here's a sample of what i have:
??4ImqNml@@QAEXABV0@@Z @604 ; ??4ImqNml@@QAEXABV0@@Z
??4ImqObj@@QAEXABV0@@Z @68 ; ??4ImqObj@@QAEXABV0@@Z
??4ImqPmo@@QAEXABV0@@Z @508 ; ??4ImqPmo@@QAEXABV0@@Z
??4ImqPro@@QAEXABV0@@Z @404 ; ??4ImqPro@@QAEXABV0@@Z
??4ImqQue@@QAEXABV0@@Z @281 ; ??4ImqQue@@QAEXABV0@@Z
?alterationDate@ImqObj@@QAE?AVImqStr@@XZ @76 ; ?alterationDate@ImqObj@@QAE?AVImqStr@@XZ
?alterationDate@ImqObj@@QAEEAAVImqStr@@@Z @75 ; ?alterationDate@ImqObj@@QAEEAAVImqStr@@@Z
?alterationTime@ImqObj@@QAE?AVImqStr@@XZ @78 ; ?alterationTime@ImqObj@@QAE?AVImqStr@@XZ
?alterationTime@ImqObj@@QAEEAAVImqStr@@@Z @77 ; ?alterationTime@ImqObj@@QAEEAAVImqStr@@@Z
?alternateSecurityId@ImqObj@@QBE?AVImqBin@@XZ @79 ; ?alternateSecurityId@ImqObj@@QBE?AVImqBin@@XZ
?alternateUserId@ImqObj@@QBE?AVImqStr@@XZ @64 ; ?alternateUserId@ImqObj@@QBE?AVImqStr@@XZ
?applicationId@ImqPro@@QAE?AVImqStr@@XZ @411 ; ?applicationId@ImqPro@@QAE?AVImqStr@@XZ
?applicationId@ImqPro@@QAEEAAVImqStr@@@Z @409 ; ?applicationId@ImqPro@@QAEEAAVImqStr@@@Z
?applicationType@ImqPro@@QAEEAAJ@Z @408 ; ?applicationType@ImqPro@@QAEEAAJ@Z
?applicationType@ImqPro@@QAEJXZ @412 ; ?applicationType@ImqPro@@QAEJXZ
2) if i can't use the c++ code, what do they mean by using the c code? Do i just follow the c samples and compile them with my c++ builder?
Any help is appreciated. My main goal is to be able to make calls to a Websphere MQ client from a BC++B 6.0 program.
Thank you very much in advance,
Ben |
|
Back to top |
|
 |
boutwater |
Posted: Tue Sep 13, 2005 5:16 am Post subject: Almost |
|
|
Novice
Joined: 12 Sep 2005 Posts: 12
|
I've think i've come close to an answer, but i think that is as far as i'm going to get. I don't think i'll be able to deal with the name mangleing of C++ like everyone on this site already said. However, being an optomist, i've included this post to see if anyone may have an answer for me. THanks for your help,
Ben
Hello,
I read through the article (http://www.devarticles.com/c/a/Cplusplus/DLL-Conventions-Issues-and-Solutions-Part-II/3/), and it all makes sense to me, but I am still having one problem. The file produced by IMPDEF is very confusing to me. It doesn’t look much like what is described in this article. Below is a sample (only a small portion) of my IMPDEF file. How am i supposed to change this? Or won't i be able to because of the name mangling?
??4ImqAir@@QAEXABV0@@Z @652 ; ??4ImqAir@@QAEXABV0@@Z
??4ImqDst@@QAEXABV0@@Z @553 ; ??4ImqDst@@QAEXABV0@@Z
??4ImqMgr@@QAEXABV0@@Z @124 ; ??4ImqMgr@@QAEXABV0@@Z
??4ImqNml@@QAEXABV0@@Z @604 ; ??4ImqNml@@QAEXABV0@@Z
??4ImqObj@@QAEXABV0@@Z @68 ; ??4ImqObj@@QAEXABV0@@Z
??4ImqPmo@@QAEXABV0@@Z @508 ; ??4ImqPmo@@QAEXABV0@@Z
??4ImqPro@@QAEXABV0@@Z @404 ; ??4ImqPro@@QAEXABV0@@Z
??4ImqQue@@QAEXABV0@@Z @281 ; ??4ImqQue@@QAEXABV0@@Z
?alterationDate@ImqObj@@QAE?AVImqStr@@XZ @76 ; ?alterationDate@ImqObj@@QAE?AVImqStr@@XZ
?alterationDate@ImqObj@@QAEEAAVImqStr@@@Z @75 ; ?alterationDate@ImqObj@@QAEEAAVImqStr@@@Z
?alterationTime@ImqObj@@QAE?AVImqStr@@XZ @78 ; ?alterationTime@ImqObj@@QAE?AVImqStr@@XZ
?alterationTime@ImqObj@@QAEEAAVImqStr@@@Z @77 ; ?alterationTime@ImqObj@@QAEEAAVImqStr@@@Z
?alternateSecurityId@ImqObj@@QBE?AVImqBin@@XZ @79 ; ?alternateSecurityId@ImqObj@@QBE?AVImqBin@@XZ
?alternateUserId@ImqObj@@QBE?AVImqStr@@XZ @64 ; ?alternateUserId@ImqObj@@QBE?AVImqStr@@XZ
?applicationId@ImqPro@@QAE?AVImqStr@@XZ @411 ; ?applicationId@ImqPro@@QAE?AVImqStr@@XZ
?applicationId@ImqPro@@QAEEAAVImqStr@@@Z @409 ; ?applicationId@ImqPro@@QAEEAAVImqStr@@@Z
?applicationType@ImqPro@@QAEEAAJ@Z @408 ; ?applicationType@ImqPro@@QAEEAAJ@Z |
|
Back to top |
|
 |
jefflowrey |
Posted: Tue Sep 13, 2005 5:20 am Post subject: |
|
|
Grand Poobah
Joined: 16 Oct 2002 Posts: 19981
|
The last time I did anything with Borland and MQ, I ended up linking against the ActiveX dll (MQAX200.dll) and used that interface.
You should also be able to use the plain MQ C interface without any trouble. _________________ I am *not* the model of the modern major general. |
|
Back to top |
|
 |
boutwater |
Posted: Wed Sep 14, 2005 6:17 am Post subject: sample code |
|
|
Novice
Joined: 12 Sep 2005 Posts: 12
|
Thank you very much. This is the answer i've been searching for for the past two days. Do you know where i can find some sample code of the mqax200 activex implementation? I've got that in and compiling, but I don't knwo what calls to make to allocate the session in borland, and things like that. Thanks,
Ben |
|
Back to top |
|
 |
jefflowrey |
Posted: Wed Sep 14, 2005 6:40 am Post subject: |
|
|
Grand Poobah
Joined: 16 Oct 2002 Posts: 19981
|
|
Back to top |
|
 |
boutwater |
Posted: Wed Sep 14, 2005 10:26 am Post subject: last question |
|
|
Novice
Joined: 12 Sep 2005 Posts: 12
|
Thanks Jeff,
I'm able to connect to the queue now. The last problem i'm having is making the call to put to the queue. I have this code:
MyMsg->ConnectTo(MyMQSession->AccessMessage());
MyMsg->WriteString(WideString("I think i put a message to the queue"));
MyQ->Put(MyMsg);
Where MyMsg is of type MQMessage and MyQ is of type MQQueue. It is erroring on the 3rd line saying:
[C++ Error] Main.cpp(502): E2342 Type mismatch in parameter 'msg' (wanted 'IDispatch *', got 'TMQMessage *')
Do you know how I make this call? I need to send it the message, but the method wants an IDispatch. The Delphi code i was looking at was like this:
mqQueue.Put(mqmsgPut.DefaultInterface,
mqptmsgOptions.DefaultInterface);
but I don't even see DefaultInterface as a property or method of MQMessage. Thanks again for your help,
Ben |
|
Back to top |
|
 |
jefflowrey |
Posted: Wed Sep 14, 2005 10:37 am Post subject: |
|
|
Grand Poobah
Joined: 16 Oct 2002 Posts: 19981
|
I don't remember details at that level...
I do think I know where I've got some private sample code at home.
I'll see if I can dig it up, and extract something useful and non-proprietary....
I don't remember using AccessMessage, though. I think I created new message objects, and got the Queue using AccessQueue. _________________ I am *not* the model of the modern major general. |
|
Back to top |
|
 |
boutwater |
Posted: Wed Sep 14, 2005 10:51 am Post subject: Thanks |
|
|
Novice
Joined: 12 Sep 2005 Posts: 12
|
|
Back to top |
|
 |
boutwater |
Posted: Thu Sep 15, 2005 6:46 am Post subject: code |
|
|
Novice
Joined: 12 Sep 2005 Posts: 12
|
I'm able to compile finally compile, but i'm not able to connect. I can't connect to the QM and keep getting the reason code "2058". Can you see anything I'm doing wrong? Here's the code:
void __fastcall TMainForm::Button3Click(TObject *Sender)
{
putenv("MQSERVER=CHANNEL1/TCP/10.1.1.32(1414)");
AnsiString TempS;
TempS = getenv("MQSERVER");
MyMQSession->Connect();
OutToMemo(flt_PLC,2,"Session Created");
MyQM->set_name(WideString("queue.manager.1"));
WideString QMStrng;
QMStrng = "queue.manager.1";
MyQM->ConnectTo(MyMQSession->AccessQueueManager(QMStrng));
if (MyMQSession->CompletionCode == MQCC_FAILED) {
TempS.sprintf("Session not connected. Reason: %d %s",MyMQSession->ReasonCode,AnsiString(MyMQSession->ReasonName));
OutToMemo(flt_PLC,2,TempS);
} else {
TempS.sprintf("Queue Manager %s Connected",AnsiString(MyQM->get_name()));
OutToMemo(flt_PLC,2,TempS);
}
MyQ->ConnectTo(MyQM->AccessQueue(WideString("dcs.mcm.test.queue.ddd"),MQOO_OUTPUT | MQOO_INPUT_AS_Q_DEF));
if (MyQM->CompletionCode == MQCC_FAILED) {
TempS.sprintf("Session not connected. Reason: %d %s",MyQM->ReasonCode,AnsiString(MyQM->ReasonName));
OutToMemo(flt_PLC,2,TempS);
} else {
TempS.sprintf("Session connected. Name: %s",MyQ->get_Description());
OutToMemo(flt_PLC,2,TempS);
}
MyPutOptions->ConnectTo(MyMQSession->AccessPutMessageOptions());
MyPutOptions->set_Options(MQPMO_NEW_MSG_ID | MQPMO_SET_IDENTITY_CONTEXT);
}
//---------------------------------------------------------------------------
//--Code Bottom
void __fastcall TMainForm::Button2Click(TObject *Sender)
{
MyMsg->ConnectTo(MyMQSession->AccessMessage());
MyMsg->WriteString(WideString("I think i put a message to the queue"));
MyQ->Put(MyMsg->GetDefaultInterface());
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::Button1Click(TObject *Sender)
{
MyQ->Get(MyMsg->GetDefaultInterface());
OutToMemo(flt_PLC,2,AnsiString(MyMsg->ReadString(20)));
}
//---------------------------------------------------------------------------
Thanks for all your help,
Ben |
|
Back to top |
|
 |
jefflowrey |
Posted: Thu Sep 15, 2005 8:25 am Post subject: |
|
|
Grand Poobah
Joined: 16 Oct 2002 Posts: 19981
|
Is your queue manager named 'queue.manager.1' or 'QUEUE.MANAGER.1'?
The way you have coded it, MQ is asking for 'QUEUE.MANAGER.1'.
I didn't get a chance last night to look at my old code. Will try to find time tonight... _________________ I am *not* the model of the modern major general. |
|
Back to top |
|
 |
boutwater |
Posted: Thu Sep 15, 2005 9:06 am Post subject: lower case |
|
|
Novice
Joined: 12 Sep 2005 Posts: 12
|
my queue manager is set up on the server as all lower case: queue.manager.1
That's how i'm calling it. Unless there is some switch that changes it to upper case. You said that i was sending it as all caps. Was that just a typo, or is there some option that switches the string to all caps? Thanks,
Ben |
|
Back to top |
|
 |
jefflowrey |
Posted: Thu Sep 15, 2005 9:25 am Post subject: |
|
|
Grand Poobah
Joined: 16 Oct 2002 Posts: 19981
|
Maybe I'm confusing myself. But I don't think so.
MQ always uppercases names unless they are enclosed in single quotes.
So try
Code: |
QMStrng = "'queue.manager.1'"; |
That's double-quote, single-quote, queue.manager.1, single-quote, double-quote. _________________ I am *not* the model of the modern major general.
Last edited by jefflowrey on Thu Sep 15, 2005 11:16 am; edited 1 time in total |
|
Back to top |
|
 |
boutwater |
Posted: Thu Sep 15, 2005 10:34 am Post subject: environment variable |
|
|
Novice
Joined: 12 Sep 2005 Posts: 12
|
I finally got things working...mostly. I still can't get from the queue all the time, but i can connect and write to it. The problem i was having was due to the environment variable not being added. I tried to add it to windows, to no avail. Finally, i added it through the environment variables options box withing the Borland IDE and it worked! I just added this:
Variable name: MQSERVER
Variable value: SYSTEM.ADMIN.SVRCONN/TCP/HOSTNAME(1414)
Thanks for all your help. If you have any thoughts on why i'd be able to write but not read, i'd appreciate them. Thanks again,
Ben |
|
Back to top |
|
 |
jefflowrey |
Posted: Thu Sep 15, 2005 11:17 am Post subject: |
|
|
Grand Poobah
Joined: 16 Oct 2002 Posts: 19981
|
You can never GET from queues that are not QLOCAL on the queue manager you are connected to.
You can't GET unless you've opened the queue for Input.
The reason code coming back from the GET will go a long way to help you understand why it didn't work. _________________ I am *not* the model of the modern major general. |
|
Back to top |
|
 |
boutwater |
Posted: Thu Sep 15, 2005 12:50 pm Post subject: All right |
|
|
Novice
Joined: 12 Sep 2005 Posts: 12
|
Thank you very much Jeff! Everything is working now. It took me longer than i would have liked, but at least it's working. The last issue i had was that i needed this line before the Get:
GetMsg->ConnectTo(MyMQSession->AccessMessage());
So it's working now. Thanks for your assistance,
Ben |
|
Back to top |
|
 |
|