CORBA IIOPNet和OmniORBpy,远程方法调用与valuetype参数问题



我的范围:我正试图为两个应用程序创建一个CORBA解决方案,一个在。net端(服务器),另一个在python(客户端)。我使用IIOPNet生成服务器和idl,使用OmniORBpy生成存根和客户端调用。一般是为简单的调用工作,如典型的例子:加法。但是当我尝试用自定义类调用方法时,它不起作用。

我有这个类在服务器端(我的Remove对象)从客户端调用:

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, omniorb -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无关紧要),抱歉这么大的帖子。

我想你忘记添加由IDLCompiler生成的接口存根了。

public class MyRemoteObject : MarshalByRefObject, module1.module2.module3.MyRemoteObject
{
    public override object InitializeLifetimeService()
    {
        return null;
    }
    public bool DoSomething(InterfaceRequest requestData)
    {
        return true;
    }    
}

你需要在c#中使用以下规则实现valuetype:[现在不是你的错误,但你迟早会得到这个错误]。

  • 你实现了一个类XYZImpl,其中XYZ是值类型的类型名
  • XYZImpl继承自抽象类XYZ(该类由IDLToCLSgenerator生成)
  • XYZImpl和XYZ在同一个命名空间
  • XYZImpl是可序列化的
  • XYZImpl有一个无参数公共构造函数
  • XYZImpl不是抽象的
  • XYZImpl实现了所有继承的抽象方法和属性链接

只要记住,你需要打开一个IIOPServerChannel:

int port = 0;
IiopChannel chan = new IiopChannel(port);
ChannelServices.RegisterChannel(chan);

相关内容

  • 没有找到相关文章

最新更新