CORBA IIOPNet 和 OmniORBpy,带有 valuetype 参数问题的远程方法调用
我的范围:我正在尝试为两个应用程序创建一个 CORBA 解决方案,一个在 .NET 端(服务器),另一个在 python(客户端)上。我使用 IIOPNet 进行服务器和 IDL 生成,使用 OmniORBpy 进行存根生成和客户端调用。一般来说,适用于简单的调用,例如典型示例:Adder。但是当 ai 尝试使用自定义类调用方法时,它不起作用。
我在服务器端有这个类(我的删除对象)可以从客户端调用:
public class MyRemoteObject : MarshalByRefObject
{
public override object InitializeLifetimeService()
{
return null;
}
public bool DoSomething(InterfaceRequest requestData)
{
return true;
}
}
输入参数类类型在服务器端声明如下(非常简单):
[Serializable]
public class InterfaceRequest
{
public int SiteId;
public int UserId;
}
我使用 CLSIDLGenerator 生成我的 IDL,后来我的 python 存根如“omniidl” -bpython -CPython ...”,直到这里一切正常。
所以我启动服务器(VS调试环境),现在在我的客户端代码上我解析了服务名称,我成功缩小了远程对象并创建了我的请求对象,但是当我尝试这样做时:
request = InterfaceRequest()
request.SiteId = 1
request.UserId = 3
result = remoteObj.DoSomething(request)
Python在没有警告的情况下爆炸了,没有例外,任何类型的消息(我将omniORB配置文件上的跟踪标签更新为最高[40],但没有任何内容被跟踪),它只是崩溃了,我尝试了很多东西,但总是得到相同的结果。当然,问题与参数有关(我猜)。
我像这样运行客户端: python client.py -ORBInitRef NameService=corbaname::localhost:8087
(我的最后一种方法:Python 对象引用架构和按值传递的一致值类型参数在某些时候不匹配)
技术详细信息: >NET 4.0、IIOPNet(最后)、Python 2.6、omniORB-4.1.5、omniORBpy-3.5。
感谢每一个帮助,我对此有点困惑,谢谢。
是的,为 MyRemoteObject 生成的 IDL 是这样的: .....
module module1 {
module module2 {
module module3 {
module module4 {
interface MyRemoteObject {
boolean TestConnection(in double value)
raises (::Ch::Elca::Iiop::GenericUserException);
bool DoSomenthing(in ::module1::module2::module3::InterfaceRequest requestData)
raises (::Ch::Elca::Iiop::GenericUserException);
};
当然
但既然你提到了这一点,我只是注意到在同一个文件(myRemoteObject.idl)上我有一个表示 InterfaceRequest 类型的结构,但像这样是空的:
module module1 {
module module2 {
module module3 {
valuetype InterfaceRequest;
};
};
};
我生成了它IDL 其他地方有正确的内容:
valuetype InterfaceRequest {
public long SiteId;
public long UserId;
};
奇怪,也许是我生成这些东西的顺序,这很重要吗?,显然这里有问题,对吧?
最后,我的这几个类(远程和参数类型)的 python 存根如下所示:
class _objref_MyRemoteObject (CORBA.Object):
_NP_RepositoryId = MyRemoteObject._NP_RepositoryId
def __init__(self):
CORBA.Object.__init__(self)
def TestConnection(self, *args):
return _omnipy.invoke(self, "TestConnection", _0_module1.module2.module3.module4.MyRemoteObject._d_TestConnection, args)
def DoSomething(self, *args):
return _omnipy.invoke(self, "DoSomething", _0_module1.module2.module3.module4.MyRemoteObject._d_DoSomething, args)
__methods__ = ["TestConnection", "DoSomething"] + CORBA.Object.__methods__
和 InterfaceRequest:
class InterfaceRequest (_0_CORBA.ValueBase):
_NP_RepositoryId = "IDL:module1/module2/module3/InterfaceRequest:1.0"
def __init__(self, *args, **kwargs):
if args:
if len(args) != 2:
raise TypeError("InterfaceRequest() takes 2 arguments "
"(%d given)" % len(args))
self.SiteId = args[0]
self.UserId = args[1]
if kwargs:
self.__dict__.update(kwargs)
因此,即使 IDL 不太正确(只是猜测),最后 python 存根也会生成正确的内容,并且正确的道路。
感谢您的帮助(我已经更改了真实姓名,希望 ID 不重要),对这么大的帖子感到抱歉。
My scope: I'm trying to create a CORBA solution for two apps one at .NET side (server) and the other on python (client). I'm using IIOPNet for server and IDLs generation and OmniORBpy for Stubs generations and client calls. In general is working for simple calls like the typical example: Adder. But when a i try to call a method with a custom class it doesn't work.
I have this class on server side(my Remove Object) to be called from the client :
public class MyRemoteObject : MarshalByRefObject
{
public override object InitializeLifetimeService()
{
return null;
}
public bool DoSomething(InterfaceRequest requestData)
{
return true;
}
}
The input param class type is declared like this on server side (quite simple):
[Serializable]
public class InterfaceRequest
{
public int SiteId;
public int UserId;
}
I generate my IDLs using CLSIDLGenerator and later my python stubs like "omniidl -bpython -CPython ...", until here everything is OK.
So i start the server (VS debug environment) and now on my client code i resolve the service name, i narrow my remote object successfully and i create my request object but when i try to do this:
request = InterfaceRequest()
request.SiteId = 1
request.UserId = 3
result = remoteObj.DoSomething(request)
Python blows up with no warning, no exception, any message of any kind, (i updated trace label on my omniORB config file to the highest [40] but nothing is getting traced), it simply crashes, i have tried a lot of stuff and i get always same result. The problem is related to the param of course (i guess).
I'm running the client side like this:
python client.py -ORBInitRef NameService=corbaname::localhost:8087
(My last approach: python object reference architecture and conforming value type param passed by value are not matching at some point)
Tech details: NET 4.0, IIOPNet (last), Python 2.6, omniORB-4.1.5, omniORBpy-3.5.
Every help is appreciated, i'm little stuck with this, Thanks.
Yes the IDL generated for MyRemoteObject is this one:
.....
module module1 {
module module2 {
module module3 {
module module4 {
interface MyRemoteObject {
boolean TestConnection(in double value)
raises (::Ch::Elca::Iiop::GenericUserException);
bool DoSomenthing(in ::module1::module2::module3::InterfaceRequest requestData)
raises (::Ch::Elca::Iiop::GenericUserException);
};
.....
But now that you mentioned this, i just noticed that on that very same file (myRemoteObject.idl) i have a structure representing the InterfaceRequest type but empty like this:
module module1 {
module module2 {
module module3 {
valuetype InterfaceRequest;
};
};
};
And of course i generate that IDL somewhere else with the right content:
valuetype InterfaceRequest {
public long SiteId;
public long UserId;
};
Weird, maybe is the order in which i'm generating this stuff, is that important?, obviously there is something wrong here right?
Finally my python stubs for these couple of classes (remote and parameter type) looks like this:
class _objref_MyRemoteObject (CORBA.Object):
_NP_RepositoryId = MyRemoteObject._NP_RepositoryId
def __init__(self):
CORBA.Object.__init__(self)
def TestConnection(self, *args):
return _omnipy.invoke(self, "TestConnection", _0_module1.module2.module3.module4.MyRemoteObject._d_TestConnection, args)
def DoSomething(self, *args):
return _omnipy.invoke(self, "DoSomething", _0_module1.module2.module3.module4.MyRemoteObject._d_DoSomething, args)
__methods__ = ["TestConnection", "DoSomething"] + CORBA.Object.__methods__
And the InterfaceRequest:
class InterfaceRequest (_0_CORBA.ValueBase):
_NP_RepositoryId = "IDL:module1/module2/module3/InterfaceRequest:1.0"
def __init__(self, *args, **kwargs):
if args:
if len(args) != 2:
raise TypeError("InterfaceRequest() takes 2 arguments "
"(%d given)" % len(args))
self.SiteId = args[0]
self.UserId = args[1]
if kwargs:
self.__dict__.update(kwargs)
So even if the IDLs are not quite right (just guessing) at the end the python stubs are getting generated with the right content and right paths.
Thanks for the help (i have changed real names, hope id doesn't matter) and sorry about so large post.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我认为您忘记添加由 IDLCompiler 生成的接口存根。
您需要使用以下规则在 C# 中实现 valuetype:
[现在不是你的错误,但你迟早会得到这个错误]。
链接
请记住,您需要打开一个 IIOPServerChannel 执行以下操作:
I think that you forgot to add the interface stub, generated by IDLCompiler.
You need to implement the valuetype in C# using these rules bellow:
[It's not your error now, but you gonna get this error soon or later].
Link
Just remembering, you need to open an IIOPServerChannel doing: