2011-08-30 43 views
2

我的作用域:我想創建一個在.NET端(服務器)和另一個在Python(客戶端)上的兩個應用程序的CORBA解決方案。我使用IIOPNet生成服務器和IDL,並使用OmniORBpy生成存根和客戶端調用。一般來說,就像典型的例子一樣簡單的調用:加法器。但是,當我嘗試調用一個自定義類的方法它不起作用。CORBA IIOPNet和OmniORBpy,遠程方法調用與值類型參數問題

我有服務器端(我刪除對象)這個類必須從客戶端調用:

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和後來的我的python存根(如「omniidl -bpython -CPython ...」)生成我的IDL,直到這裏一切正常。

所以我啓動服務器(VS調試環境),現在我的客戶端代碼我解析服務名稱,我縮小我的遙控成功的對象,並創建我的請求對象,但是當我嘗試這樣做:

request = InterfaceRequest() 
request.SiteId = 1 
request.UserId = 3 

result = remoteObj.DoSomething(request) 

Python沒有任何警告,沒有例外,任何類型的消息,(我更新我的omniORB配置文件上的跟蹤標籤到最高[40]但沒有任何跟蹤),它只是崩潰,我試過了很多東西,我總是得到相同的結果。問題與當然的參數有關(我猜)。

我運行客戶端這樣的: 蟒蛇client.py -ORBInitRef名稱服務= corbaname ::本地主機:8087

(我最後的辦法:Python對象的參考架構,符合價值型PARAM傳遞按價值在某些點不匹配)

技術細節:NET 4.0,IIOPNet(最後),Python 2.6,omniORB-4.1.5,omniORBpy-3.5。

每一個幫助表示讚賞,我有點卡住了,謝謝。


是在IDL的MyRemoteObject產生的是這個: .....

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; 
}; 

奇怪,也許是爲了在我生成這個東西,是重要的?顯然是有什麼錯在這裏權?

最後我對這些夫婦的類(遠程和參數類型)蟒蛇存根看起來是這樣的:

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並不重要),對於如此之大的帖子感到抱歉。

+0

是否有一個的IDL'interface MyRemoteObject'?您需要實現IDL接口,如:「public class MyRemoteObject:MarshalByRefObject,moduleIDL.module2.MyRemoteObject」。 – Makah

+0

你可以添加IDL文件嗎? – Makah

+0

我已使用生成的IDL和存根更新了帖子。謝謝,我使用Windows 7 64位,以防萬一這可能是一個問題(但我懷疑它是因爲除了這種類型的調用以外的其他任何工作)。 – michel

回答

0

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

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

    public bool DoSomething(InterfaceRequest requestData) 
    { 
     return true; 
    }  
} 

您需要使用波紋管這些規則來實現在C#中值類型: [現在不是你的錯誤,但你會很快或以後出現此錯誤。

  • 你沒有實現類XYZImpl,其中XYZ是值類型
  • XYZImpl從抽象類繼承的類型名稱XYZ(由IDLToCLSgenerator生成的這個類)
  • XYZImpl是在同一個命名空間作爲XYZ
  • XYZImpl是序列化
  • XYZImpl有一個無參數的公共構造
  • XYZImpl不是抽象
  • XYZImpl實現了所有繼承的抽象方法和屬性 Link

只要記住,你需要打開一個IIOPServerChannel做:

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

我真的不明白爲什麼我必須繼承我從我的類生成的接口第一次,我缺少這裏的工作流程的一部分,反正我爲我的InterfaceRequest類創建一個空的接口,現在稱爲InterfaceRequestImpl on NET方面手動和IT作品!!!。但是,你介意給我解釋你對IDLToCLSCompiler.exe生成的DLL做了什麼,你是否將它作爲參考包含在你的項目中,並從它們相應的接口繼承所有類型?看起來像對我來說很醜陋的過程我寧願只要我可以手動做。謝謝。 – michel

+0

這並不難看。 IDL是一種合約,就像您的服務API一樣。設置你不會每次都改變它。 – Makah

+0

InterfaceRequest是您的valueType,您不需要創建假設的接口。只需創建一個名爲InterfaceRequestImpl的類,並從抽象類InterfaceRequest(從IDLToCLSCompiler.exe中生成的dll)繼承。如果我們沒有這些規則來裝入一個valuetype,則ORB找不到要實例化的類。這是IIOP.NET必須找到您的實施方式。 [很難用幾句話寫:-)] – Makah

相關問題