gpt4 book ai didi

c++ - CORBA omniORB 在解析名称上下文后无法获取远程对象

转载 作者:太空宇宙 更新时间:2023-11-04 13:18:24 26 4
gpt4 key购买 nike

我有如下的 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();
}

更新至下午 5 点:事实上,服务器端代码也有同样的问题 server->authenticate is never called due to nil reference。

猜测:使用 idl2cpp 工具生成的代理和 stub 会不会有问题?

UPDATE-7:30PMstubs not ok 上的歧义也消失了,在重新生成 stubs 并再次重建客户端和服务器应用程序后问题仍然存在

更新 3-31|11AM我正在使用超过 10 年的 omniORB 4.0.3。这在使用 VC6 编译的早期 Windows 操作系统版本中效果很好,我怀疑在 VS 2008 上重新编译时是否存在问题。只是考虑升级到去年发布的 ommiORB 4.2。就是一头雾水……

更新 3-31|5:30PM目前构建omniORB4.2.1源代码。当我这样做时,我仍然想知道链接在旧系统中生成的 .lib 文件是否有任何问题。在这种情况下,我在 Windows 7 中使用的 omniORB .lib 文件是在 Windows XP 上构建的,这会是一个问题吗?连this帖子无法回答,我有一个旧的 .lib 可以很好地编译和链接,没有任何问题,甚至运行时也没有崩溃

更新 4-01|4:30PM实际上我注意到没有服务器在运行,我之前发布的服务器代码也是客户端,我现在更新了真正的服务器代码(将名称绑定(bind)到服务器obj的代码)。但即使经过此更正,问题仍然存在

最佳答案

我终于解决了这个问题。代码有2个问题问题 1 我已经更新了问题(缺少服务器代码)问题 2 是名称上下文绑定(bind)..

以下是服务器中 bindObjectToName 的修改版本

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) ) {
// cerr << "Failed to narrow the root naming context." << endl;
return 0;
}
}
catch(CORBA::ORB::InvalidName& ex) {
// This should not happen!
// cerr << "Service required is invalid [does not exist]." << endl;
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*) "DataCollectionS"; // 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.
testContext = rootContext->bind_new_context(contextName);
}
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);
testContext = CosNaming::NamingContext::_narrow(obj);
if( CORBA::is_nil(testContext) ) {
// cerr << "Failed to narrow naming context." << endl;
return 0;
}
}

// Bind sender :
CosNaming::Name objectName;
objectName.length(1);
objectName[0].id = (const char*) "clienT"; // string copied
objectName[0].kind = (const char*) "sendeR"; // string copied

try {
testContext->bind(objectName, objref);
}
catch(CosNaming::NamingContext::AlreadyBound& ex) {
testContext->rebind(objectName, objref);
}
// Note: Using rebind() will overwrite any Object previously bound
// to /test/Echo with obj.
// Alternatively, bind() can be used, which will raise a
// CosNaming::NamingContext::AlreadyBound exception if the name
// supplied is already bound to an object.

// Bind receiver :
CosNaming::Name objectName2;
objectName2.length(1);
objectName2[0].id = (const char*) "clienT"; // string copied
objectName2[0].kind = (const char*) "receiveR"; // string copied

try {
testContext->bind(objectName2, objref);
}
catch(CosNaming::NamingContext::AlreadyBound& ex) {
testContext->rebind(objectName2, objref);
}


// Amendment: When using OrbixNames, it is necessary to first try bind
// and then rebind, as rebind on it's own will throw a NotFoundexception if
// the Name has not already been bound. [This is incorrect behaviour -
// it should just bind].

}
catch(CORBA::COMM_FAILURE& ex) {
//cerr << "Caught system exception COMM_FAILURE -- unable to contact the "
// << "naming service." << endl;
return 0;
}
catch(CORBA::SystemException&) {
//cerr << "Caught a CORBA::SystemException while using the naming service."
// << endl;
return 0;
}

return 1;
}

以及客户端代码中修改后的getObjectReference下面静态 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& ex) {
// This should not happen!
// cerr << "Service required is invalid [does not exist]." << endl;
_BRDTRACE("getObjRef: service required is invalid.\n");
exit(0);
return CORBA::Object::_nil();
}


// Create a name object, containing the name test/context:
CosNaming::Name name;
name.length(2);

name[0].id = (const char*) "birdsEYE"; // string copied
name[0].kind = (const char*) "DataCollectionS"; // string copied
name[1].id = (const char*) "clienT";
name[1].kind = (const char*) "sendeR";
// 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& ex) {
// This exception is thrown if any of the components of the
// path [contexts or the object] aren't found:
//cerr << "Context not found." << endl;
_BRDTRACE("getObjRef: context not found.\n");
exit(0);
}
catch(CORBA::COMM_FAILURE& ex) {
//cerr << "Caught system exception COMM_FAILURE -- unable to contact the "
// << "naming service." << endl;
_BRDTRACE("getObjRef: caught system exception COMM_FAILURE.\n");
exit(0);
}
catch(CORBA::SystemException&) {
//cerr << "Caught a CORBA::SystemException while using the naming service."
//<< endl;
_BRDTRACE("getObjRef: caught system exception while using the name service.\n");
exit(0);
}

return CORBA::Object::_nil();
}

关于c++ - CORBA omniORB 在解析名称上下文后无法获取远程对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36306835/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com