在使用 C++ Builder 4 (BCB4) 開發 CORBA 應用時,若直接使用內建的 CORBA Server Wizard 往往會遇到莫名其妙的問題,而 VisiBroker 提供的範例卻能正常編譯執行。本文記錄從頭手動建立 CORBA Server 並整合 Name Service 的完整步驟,幫助開發者避開常見陷阱。
檔案:order.idl
interface Order {
string Name();
};
order.idl,編譯專案產生 Stub/Skeleton 程式碼。File → New → Multitier → Corba Object Implementation,選擇 order.idl 介面 Order,自動產生 OrderServer.cpp。修改實作:
char* OrderImpl::Name() {
return "Hi, I am Test CorbaServer";
}
儲存專案為 tcnServer.bpr,編譯執行測試。
在命令列執行 osfind.exe(位於 VisiBroker bin 目錄),確認輸出中出現:
REPOSITORY ID: IDL:Order:1.0
OBJECT NAME: OrderObject
表示伺服器已向 OAD(Object Activation Daemon)註冊成功。
tcnServer.cpp 加入標頭:#include "CosNaming_c.hh"$(VBroker)\lib\name_br.lib,專案會自動產生 USELIB 指令。boa->obj_is_ready(&order_OrderObject); 之後插入綁定程式碼:// 從命令列參數取得 NameComponent
const char* id = argv[1];
const char* kind = argv[2];
// 取得預設 NamingContext
CosNaming::NamingContext_var context = CosNaming::NamingContext::_bind();
// 建立 Name 物件(單一 NameComponent)
CosNaming::Name name;
name.length(1);
name[0].id = id;
name[0].kind = kind;
// 綁定物件參考
context->bind(name, &order_OrderObject);
cout << "The object is bound: \"" << name[0].id << "\" \"" << name[0].kind << "\"" << endl;
重新編譯專案。
start nameextf MyTester test.logstart tcnServer MyName MyKindosfind,應看到 OBJECT NAME: OrderObject 出現在 Repository 列表中。order.idl。Order,Object Name 填 OrderObject。boa->impl_ready();。#include "CosNaming.hh" 並連結 name_br.lib。main() 中解析名稱並呼叫:const char* id = argv[1];
const char* kind = argv[2];
CosNaming::NamingContext_var context = CosNaming::NamingContext::_bind();
CosNaming::Name name;
name.length(1); name[0].id = id; name[0].kind = kind;
CORBA::Object_var obj = context->resolve(name);
Order_var order = Order::_narrow(obj);
cout << "test result: " << order->Name() << endl;
order.idl。OrderObject。try {
Edit1->Text = "正在查找名為:{" + Edit2->Text + "," + Edit3->Text + "}的對象";
CosNaming::NamingContext_var context = CosNaming::NamingContext::_bind();
CosNaming::Name name;
char id[32], kind[32];
strcpy(id, Edit2->Text.c_str());
strcpy(kind, Edit3->Text.c_str());
name.length(1);
name[0].id = id; name[0].kind = kind;
CORBA::Object_var object = context->resolve(name);
Order_var test = Order::_narrow(object);
if (!CORBA::is_nil(test))
Edit1->Text = AnsiString(test->Name());
else
Edit1->Text = "訪問失敗!";
}
catch (const CORBA::Exception& e) {
ShowMessage(e._description.name());
exit(1);
}
test.log 重新開始。nameextf 不需頻繁重啟,保留 test.log 可維持命名狀態。完整範例專案包含 Console Server、GUI Server、Console Client、GUI Client,可作為 CORBA 開發的參考基礎。