私は以下のようなIDLを持っています
module IClientServer {
interface IClient
{
void serverResponse(in string name, in string data);
void start();
void stop();
void shutdown();
};
interface IServer
{
// Server calls back to client just once in a
// recursive call before returning.
// void one_time(in CallBack cb, in string mesg);
void DataFromX(in string name,in string data,in long lbytes,in short usg);
void Authenticate(in IClient client, in string dataToNegotiate);
// Shuts down the server.
void shutdown();
};
};
ドキュメントで提案されているように、idl2cppユーティリティ(onmiORB)を使用してプロキシとスケルトンを生成し、生成されたファイルをサーバーとクライアントアプリにリンクしました
次に、ネームサービス(omniNames)を開始し、コマンドライン引数を使用せずに接続するサーバーおよびクライアントアプリのドキュメントで提案されているように、レジストリキー omniORB\InitRef を追加しました
以下はサーバーコードです
int _tmain(int argc, _TCHAR* argv[])
{
try
{
int argc = 0;
_BRDTRACE("Initializing....\n");
CORBA::ORB_var orb = CORBA::ORB_init(argc, NULL);
// cerr << "Initialized." << endl;
CORBA::Object_var obj = orb->resolve_initial_references("RootPOA");
_BRDTRACE("Resolved.\n");
PortableServer::POA_var poa = PortableServer::POA::_narrow(obj);
_BRDTRACE("Narrowed..\n");
// Obtain a reference to the object, and register it in
// the naming service.
server_i* myserver = new server_i();
// cerr << "Constructed." << endl;
obj = myserver->_this();
_BRDTRACE("obj retrieved.\n");
CORBA::String_var x;
x = orb->object_to_string(obj);
_BRDTRACE("obj to string.\n");
if( !bindObjectToName(orb, obj) )
{
// cerr << "Failed to bind obj to name." << endl;
throw;
}
_BRDTRACE("binded\n");
myserver->_remove_ref();
// cerr << "removed ref." << endl;
PortableServer::POAManager_var pman = poa->the_POAManager();
pman->activate();
_BRDTRACE("activated.\n");
// cerr << "Executing..." << endl;
orb->run();
_BRDTRACE("Terminated.\n");
myserver->shutdown();
// cerr << "Shutdown." << endl;
}
catch(CORBA::SystemException&)
{
_BRDTRACE("Caught CORBA::SystemException.\n");
}
catch(CORBA::Exception&) {
_BRDTRACE("Caught CORBA::Exception.\n");
}
catch(omniORB::fatalException&)
{
_BRDTRACE("Caught omniORB::fatalException:\n");
// cerr << " file: " << fe.file() << endl;
// cerr << " line: " << fe.line() << endl;
// cerr << " mesg: " << fe.errmsg() << endl;
}
catch(...) {
_BRDTRACE("Caught unknown exception.\n");
}
}
static CORBA::Boolean
bindObjectToName(CORBA::ORB_ptr orb, CORBA::Object_ptr objref)
{
CosNaming::NamingContext_var rootContext;
try {
// Obtain a reference to the root context of the Name service:
CORBA::Object_var obj;
obj = orb->resolve_initial_references("NameService");
// Narrow the reference returned.
rootContext = CosNaming::NamingContext::_narrow(obj);
if( CORBA::is_nil(rootContext) ) {
_BRDTRACE("Failed to narrow the root naming context.\n");
return 0;
}
}
catch(CORBA::ORB::InvalidName& ex) {
// This should not happen!
_BRDTRACE("Service required is invalid [does not exist].\n");
return 0;
}
try {
// Bind a context called "test" to the root context:
CosNaming::Name contextName;
contextName.length(1);
contextName[0].id = (const char*) "birdseye"; // string copied
contextName[0].kind = (const char*) "collections_context"; // string copied
// Note on kind: The kind field is used to indicate the type
// of the object. This is to avoid conventions such as that used
// by files (name.type -- e.g. test.ps = postscript etc.)
//CosNaming::NamingContext_var testContext;
try {
// Bind the context to root.
rootContext->bind(contextName, objref);
}
catch(CosNaming::NamingContext::AlreadyBound& ex) {
// If the context already exists, this exception will be raised.
// In this case, just resolve the name and assign testContext
// to the object returned:
CORBA::Object_var obj;
obj = rootContext->resolve(contextName);
CosNaming::NamingContext_var testContext = CosNaming::NamingContext::_narrow(obj);
if( CORBA::is_nil(testContext) ) {
_BRDTRACE("Failed to narrow naming context.\n");
return 0;
}
}
} catch(CORBA::COMM_FAILURE& ex) {
_BRDTRACE("Caught system exception COMM_FAILURE -- unable to contact the naming service.\n");
return 0;
}
catch(CORBA::SystemException&) {
_BRDTRACE("Caught a CORBA::SystemException while using the naming service.\n");
return 0;
}
return 1;
}
ただし、クライアント側の以下のコードは、名前のコンテキスト解決後に nil オブジェクトを返します。問題を把握できません。助けてください!
int _tmain(int argc, _TCHAR* argv[])
{
CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);
CORBA::Object_var objRef = orb->resolve_initial_references("NameService");
CORBA::Object_var obj = getObjectReference(orb);
IClientServer::IServer_var svr = IClientServer::IServer::_narrow(obj.in());
if( CORBA::is_nil(svr) ) { **//THIS IS WHERE THE ISSUE IS**
// _BRDTRACE("cb_client: The server reference is nil!\n");
return 0;
}
return 0;
}
static CORBA::Object_ptr
getObjectReference(CORBA::ORB_ptr orb)
{
CosNaming::NamingContext_var rootContext;
try {
// Obtain a reference to the root context of the Name service:
CORBA::Object_var obj;
obj = orb->resolve_initial_references("NameService");
// Narrow the reference returned.
rootContext = CosNaming::NamingContext::_narrow(obj);
if( CORBA::is_nil(rootContext) ) {
// cerr << "Failed to narrow the root naming context." << endl;
return CORBA::Object::_nil();
}
}
catch(CORBA::ORB::InvalidName& ) {
// This should not happen!
return CORBA::Object::_nil();
}
// Create a name object, containing the name test/context:
CosNaming::Name name;
name.length(1);
name[0].id = (const char*) "birdseye"; // string copied
name[0].kind = (const char*) "collections_context"; // string copied
// Note on kind: The kind field is used to indicate the type
// of the object. This is to avoid conventions such as that used
// by files (name.type -- e.g. test.ps = postscript etc.)
try {
// Resolve the name to an object reference.
return rootContext->resolve(name);
}
catch(CosNaming::NamingContext::NotFound& nf) {
}
catch(CORBA::COMM_FAILURE& ) {
}
catch(CORBA::SystemException&) {
}
return CORBA::Object::_nil();
}
UPDATE-5PM: 実際、サーバー側のコードにも同じ問題があります server->authenticate は nil 参照のために呼び出されません。
推測: idl2cpp ツールで生成されたプロキシとスタブに問題がある可能性はありますか?
UPDATE-7:30PM スタブのあいまいさもなくなりました。スタブを再生成し、クライアント アプリとサーバー アプリの両方を再構築した後も問題は解決しません。
UPDATE 3-31|11AM 私は 10 年以上前の omniORB 4.0.3 を使用しています。これは、VC6 でコンパイルされた以前の Windows OS バージョンではうまく機能しましたが、VS 2008 で再コンパイルしたときに問題があるとは思えません。昨年リリースされた ommiORB 4.2 へのアップグレードを考えているだけです。無知ばかりで…。
UPDATE 3-31|5:30PM 現在、omniORB4.2.1 のソース コードをビルドしています。これを行っている間、古いシステムで生成された .lib ファイルのリンクに問題があるかどうかを知りたいです。この場合、私が Windows 7 で使用している omniORB .lib ファイルは Windows XP でビルドされていますが、問題になるでしょうか? この投稿でも答えられませんでした。古い .lib があり、問題なくコンパイルおよびリンクされ、ランタイムもクラッシュしませんでした。
UPDATE 4-01|4:30PM 実際にサーバーが実行されていないことに気付きました。前に投稿したサーバー コードもクライアントです。現在、実際のサーバー コード (name をサーバー obj にバインドするコード) を更新しました。しかし、この修正後も問題は変わりません