/ Forside / Teknologi / Udvikling / C/C++ / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
C/C++
#NavnPoint
BertelBra.. 2425
pmbruun 695
Master_of.. 501
jdjespers.. 500
kyllekylle 500
Bech_bb 500
scootergr.. 300
gibson 300
molokyle 287
10  strarup 270
Corba impl af idl i c++
Fra : Jacob Just


Dato : 13-11-02 13:47

Hej, jeg er lidt i tvivl om denne impl. da det fører til problemer på
javaserveren, som resolver c++ implemtation, her er først idl filen, og
derefter c++ filen:

// idl start
// Observer-interface (Client as listener):
interface ClientListener;

interface NrReplyer
{
long getNr();
string getName();
void getThis( in ClientListener aListener, in long nr);
};

interface ClientListener
{
string getName();
void fromReplyer( in NrReplyer reply);
};

interface NrFinder
{
oneway void findNr (in ClientListener aListener, in long nr);
};

//idl end

// c++ impl
#include "Callback2.h"

class NrReplyerImpl : virtual public POA_NrReplyer {
char* name;
long nr;
public:
NrReplyerImpl();
~NrReplyerImpl();
CORBA::Long getNr();
char* getName();
void getThis(const ClientListener_ptr aListener, CORBA::Long nr );
};

NrReplyerImpl::NrReplyerImpl(){
name = "c-server";
nr = 4;
}

NrReplyerImpl:NrReplyerImpl(){
delete name;
}

char* NrReplyerImpl::getName(){
cout << "received request" << endl;
//return name;
//return CORBA::string_dup("Hello world\n");
return name;
}

void NrReplyerImpl::getThis( const ClientListener_ptr aListener, CORBA::Long
nr ){
//cout << "Contacted request for number" << nr;
}

CORBA::Long NrReplyerImpl::getNr(){
return CORBA::Long(nr);
}
//






Når jeg skal smide denne om på nameserveren gør jeg som følger, hvor nc er
nameserver:::

cout << "Running...\n" << endl;
CosNaming::Name temp(2);
temp.length(1);
temp[0].id = CORBA::string_dup("Repliers");
temp[0].kind = CORBA::string_dup("cxt");
try{
nc->bind_new_context(temp);
}
catch ( CosNaming::NamingContext::AlreadyBound& ){;}
PortableServer::ObjectId_var oid;
PortableServer::ServantBase_var theServant;
CORBA::Object_var objV;

theServant = new NrReplyerImpl();
oid = poa->activate_object(theServant.in());
objV = poa->id_to_reference(oid);

CosNaming::Name name(2);
name.length (2);
name[0].id = CORBA::string_dup ("Repliers");
name[0].kind = CORBA::string_dup ("cxt");
name[1].id = CORBA::string_dup ("c-server");
name[1].kind = CORBA::string_dup ("service");
nc->rebind(name,objV);
}
catch ( ... ){
cout << "exception caught" << endl;
}


Selve bindingen på nameserveren går smertefrit, men når jeg fra mit Java
component prøver dette:

NrReplyer subject = NrReplyerHelper.narrow(getObjectReference(objName));

Får jeg følgende exception:

org.omg.CORBA.BAD_PARAM: vmcid: 0x0 minor code: 0 completed: No

at Callback.NrReplyerHelper.narrow(NrReplyerHelper.java:60)

at NrFinderImpl.list(NrFinderImpl.java:76)

at NrFinderImpl.list(NrFinderImpl.java:70)

at NrFinderImpl.findNr(NrFinderImpl.java:21)

at Callback.NrFinderPOA._invoke(NrFinderPOA.java:38)

at
com.sun.corba.se.internal.POA.GenericPOAServerSC.dispatchToServant(Ge

nericPOAServerSC.java:517)

at
com.sun.corba.se.internal.POA.GenericPOAServerSC.internalDispatch(Gen

ericPOAServerSC.java:207)

at
com.sun.corba.se.internal.POA.GenericPOAServerSC.dispatch(GenericPOAS

erverSC.java:109)

at com.sun.corba.se.internal.iiop.ORB.process(ORB.java:252)

at
com.sun.corba.se.internal.iiop.RequestProcessor.process(RequestProces

sor.java:81)

at
com.sun.corba.se.internal.orbutil.ThreadPool$PooledThread.run(ThreadP

ool.java:106)




Håber nogen kan hjælpe det har drillet i lang tid
Mvh. Jacob Just






 
 
Mogens Hansen (13-11-2002)
Kommentar
Fra : Mogens Hansen


Dato : 13-11-02 21:45



"Jacob Just" <Jacob_Just@mail1.stofanet.dk> wrote in message
news:<3dd249ca$0$5785$ba624c82@nntp04.dk.telia.net>...

Jeg har ikke oversat noget af din kode, men den får lige et par kommentarer
med på vejen - både CORBA og C++ relaterede.

[8<8<8<]
> class NrReplyerImpl : virtual public POA_NrReplyer {
> char* name;

Brug std::string i stedet for char* - det letter dig for mange bekymringer.

[8<8<8<]
> NrReplyerImpl::NrReplyerImpl(){
> name = "c-server";
> nr = 4;
> }

Foretræk initialisering fremfor assignment i C++:

NrReplyerImpl::NrReplyerImpl() :
name("c-server"),
nr(4)
{
}


>
> NrReplyerImpl:NrReplyerImpl(){
> delete name;

Har du allokeret den memory som name peger på med "new" ?
(Hint: nej - så skal du ikke delete name)


[8<8<8<]
> char* NrReplyerImpl::getName(){
> cout << "received request" << endl;
> //return name;
> //return CORBA::string_dup("Hello world\n");
> return name;

Det er påkrævet at bruge CORBA::string_dup her.

> Når jeg skal smide denne om på nameserveren gør jeg som følger, hvor
> nc er
> nameserver:::
>
> cout << "Running...\n" << endl;
> CosNaming::Name temp(2);
> temp.length(1);
> temp[0].id = CORBA::string_dup("Repliers");
> temp[0].kind = CORBA::string_dup("cxt");
> try{
> nc->bind_new_context(temp);

Her laver du en resource-leak.
Skriv hellere:
CosNaming::NamingContext_var rnc =
nc->bind_new_context(temp);

Forslag:
Ryk eventuelt "temp" og tildelingen af "temp" ind i "try" delen - så får du
begrænset scope.

> }
> catch ( CosNaming::NamingContext::AlreadyBound& ){;}
> PortableServer::ObjectId_var oid;
> PortableServer::ServantBase_var theServant;
> CORBA::Object_var objV;

Foretræk at initialisere variable efterhånden som de erklæres, hvis det er
muligt.
Foretræk at erklære dem efterhånden som man får brug for det.

>
> theServant = new NrReplyerImpl();
> oid = poa->activate_object(theServant.in());
> objV = poa->id_to_reference(oid);
>
> CosNaming::Name name(2);
> name.length (2);
> name[0].id = CORBA::string_dup ("Repliers");
> name[0].kind = CORBA::string_dup ("cxt");
> name[1].id = CORBA::string_dup ("c-server");
> name[1].kind = CORBA::string_dup ("service");
> nc->rebind(name,objV);

Umiddelbart ser det rimeligt ud - bortset fra lidt leaks og en destructor,
der ikke virker.
Jeg har lige prøvet den tilsvarende måde at aktivere og registere objektet
(med en anden IDL), og det virker problem-frit.
Der mangler naturligvis nogle trin, som du sikkert har skåret væk:

1. Initialiser ORB'en
2. Få fat på en POA - formodentlig RootPOA
3. Aktiver POAManageren
4. Det du har skrevet i indlæget
5. Få ORB'en til at processere indkommende kald - f.eks. med "orb->run();"

Prøv eventuelt noget i retningen af (ikke test kode):
// Create a CORBA object
// First create servant
NrReplyerImp replyer_servant;
// Then register servant with POA
CORBA::Object_var replyer_obj =
poa->servant_to_reference(&replyer_servant);

// Register replyer CORBA object with naming-service
name[0].id = CORBA::string_dup ("Repliers");
name[0].kind = CORBA::string_dup ("cxt");
name[1].id = CORBA::string_dup ("c-server");
name[1].kind = CORBA::string_dup ("service");
nc->rebind(name,replyer_obj);

[8<8<8<]
>
> org.omg.CORBA.BAD_PARAM: vmcid: 0x0 minor code: 0 completed: No
>

Jeg kan ikke umiddelbart se årsagen til ovenstående exception.
Er du _sikker_ på at C++ serveren og Java clienten arbejder ud fra samme
IDL-fil ?
Er der forskel på om du kører server og klient på samme maskine eller ej ?
(Det kunne være et netværks konfigurations problem)
Har din ORB en utility til at liste hvad der er registeret i NameService ?
Er der et eksempel (klient og server) med din ORBer, som bruger NameService
og som du _ved_ virker. Så kan du skrive det tilsvarende eksempel i det
andet sprog, og så _ved_ du at problemet må ligge i det du lige har skrevet.


To råd der har hjulpet mig meget i relation til C++ og CORBA:

1)
Hvis du vil lave noget seriøst med CORBA og C++, så få (som jeg tidligere
har nævnt) fat på bogen
Advanced CORBA Programming with C++
Michi Henning, Steve Vinoski
ISBN 0-201-37927-9
og læs den.
Den siges iøvrigt også at være god for Java programmører, der skal skrive
CORBA.
I virkeligheden er der ikke særlig stor forskel på hvad der skal laves i C++
og Java.

2)
Memory-håndtering i C++ er i sig selv ikke nødvendigvis simpelt, og CORBA
gør det bestemt ikke nemmere.

Jeg har haft meget gavn af at anvende Borland C++Builder
Professional/Enterprise V5/V6 (www.borland.com) sammen C++ CORBA
implementeringen TAO (http://www.cs.wustl.edu/~schmidt/TAO.html).

C++Builder Professional/Enterprise har en feature, der hedder CodeGuard.
CodeGuard checker effektivt en lang række typiske C og C++ fejl, såsom
memory-leak, tilgang til frigivet memory, double delete, buffer over-run
etc.
CodeGuard finder også af og til fejl i ORB'en, selvom den er checket med
Purify.
For god ordens skyld: det er muligt at skrive en CORBA server eller klient
med C++ uden at der er nogen former for fejl-rapporter fra CodeGuard. Man
gør sig selv en stor tjeneste ved hele tiden at være i den tilstand.

TAO er en open-source ORB, som umiddelbart kan oversættes med C++Builder.
Hvis man oversætter såvel ORB'en som en egen applikation med CodeGuard
enabled, giver det er vældigt godt check af den samlede applikation.

Selv hvis man ikke ønsker at bruge TAO eller C++Builder til produktion, er
kombinationen også _rigtig_ god til debug og uddannelsesformål.


Venlig hilsen

Mogens Hansen



Jacob Just (16-11-2002)
Kommentar
Fra : Jacob Just


Dato : 16-11-02 10:09

Hej Mogens,
Mange tak for hjælpen, jeg har fundet mit problem, det hele bundede ud i at
jeg ikke brugte CORBA::string_dup men char*.
Mvh. Jacob Just

"Mogens Hansen" <mogens_h@dk-online.dk> skrev i en meddelelse
news:aqude5$1pne$1@news.cybercity.dk...
>
>
> "Jacob Just" <Jacob_Just@mail1.stofanet.dk> wrote in message
> news:<3dd249ca$0$5785$ba624c82@nntp04.dk.telia.net>...
>
> Jeg har ikke oversat noget af din kode, men den får lige et par
kommentarer
> med på vejen - både CORBA og C++ relaterede.
>
> [8<8<8<]
> > class NrReplyerImpl : virtual public POA_NrReplyer {
> > char* name;
>
> Brug std::string i stedet for char* - det letter dig for mange
bekymringer.
>
> [8<8<8<]
> > NrReplyerImpl::NrReplyerImpl(){
> > name = "c-server";
> > nr = 4;
> > }
>
> Foretræk initialisering fremfor assignment i C++:
>
> NrReplyerImpl::NrReplyerImpl() :
> name("c-server"),
> nr(4)
> {
> }
>
>
> >
> > NrReplyerImpl:NrReplyerImpl(){
> > delete name;
>
> Har du allokeret den memory som name peger på med "new" ?
> (Hint: nej - så skal du ikke delete name)
>
>
> [8<8<8<]
> > char* NrReplyerImpl::getName(){
> > cout << "received request" << endl;
> > //return name;
> > //return CORBA::string_dup("Hello world\n");
> > return name;
>
> Det er påkrævet at bruge CORBA::string_dup her.
>
> > Når jeg skal smide denne om på nameserveren gør jeg som følger, hvor
> > nc er
> > nameserver:::
> >
> > cout << "Running...\n" << endl;
> > CosNaming::Name temp(2);
> > temp.length(1);
> > temp[0].id = CORBA::string_dup("Repliers");
> > temp[0].kind = CORBA::string_dup("cxt");
> > try{
> > nc->bind_new_context(temp);
>
> Her laver du en resource-leak.
> Skriv hellere:
> CosNaming::NamingContext_var rnc =
> nc->bind_new_context(temp);
>
> Forslag:
> Ryk eventuelt "temp" og tildelingen af "temp" ind i "try" delen - så får
du
> begrænset scope.
>
> > }
> > catch ( CosNaming::NamingContext::AlreadyBound& ){;}
> > PortableServer::ObjectId_var oid;
> > PortableServer::ServantBase_var theServant;
> > CORBA::Object_var objV;
>
> Foretræk at initialisere variable efterhånden som de erklæres, hvis det er
> muligt.
> Foretræk at erklære dem efterhånden som man får brug for det.
>
> >
> > theServant = new NrReplyerImpl();
> > oid = poa->activate_object(theServant.in());
> > objV = poa->id_to_reference(oid);
> >
> > CosNaming::Name name(2);
> > name.length (2);
> > name[0].id = CORBA::string_dup ("Repliers");
> > name[0].kind = CORBA::string_dup ("cxt");
> > name[1].id = CORBA::string_dup ("c-server");
> > name[1].kind = CORBA::string_dup ("service");
> > nc->rebind(name,objV);
>
> Umiddelbart ser det rimeligt ud - bortset fra lidt leaks og en destructor,
> der ikke virker.
> Jeg har lige prøvet den tilsvarende måde at aktivere og registere objektet
> (med en anden IDL), og det virker problem-frit.
> Der mangler naturligvis nogle trin, som du sikkert har skåret væk:
>
> 1. Initialiser ORB'en
> 2. Få fat på en POA - formodentlig RootPOA
> 3. Aktiver POAManageren
> 4. Det du har skrevet i indlæget
> 5. Få ORB'en til at processere indkommende kald - f.eks. med
"orb->run();"
>
> Prøv eventuelt noget i retningen af (ikke test kode):
> // Create a CORBA object
> // First create servant
> NrReplyerImp replyer_servant;
> // Then register servant with POA
> CORBA::Object_var replyer_obj =
> poa->servant_to_reference(&replyer_servant);
>
> // Register replyer CORBA object with naming-service
> name[0].id = CORBA::string_dup ("Repliers");
> name[0].kind = CORBA::string_dup ("cxt");
> name[1].id = CORBA::string_dup ("c-server");
> name[1].kind = CORBA::string_dup ("service");
> nc->rebind(name,replyer_obj);
>
> [8<8<8<]
> >
> > org.omg.CORBA.BAD_PARAM: vmcid: 0x0 minor code: 0 completed: No
> >
>
> Jeg kan ikke umiddelbart se årsagen til ovenstående exception.
> Er du _sikker_ på at C++ serveren og Java clienten arbejder ud fra samme
> IDL-fil ?
> Er der forskel på om du kører server og klient på samme maskine eller ej ?
> (Det kunne være et netværks konfigurations problem)
> Har din ORB en utility til at liste hvad der er registeret i NameService ?
> Er der et eksempel (klient og server) med din ORBer, som bruger
NameService
> og som du _ved_ virker. Så kan du skrive det tilsvarende eksempel i det
> andet sprog, og så _ved_ du at problemet må ligge i det du lige har
skrevet.
>
>
> To råd der har hjulpet mig meget i relation til C++ og CORBA:
>
> 1)
> Hvis du vil lave noget seriøst med CORBA og C++, så få (som jeg tidligere
> har nævnt) fat på bogen
> Advanced CORBA Programming with C++
> Michi Henning, Steve Vinoski
> ISBN 0-201-37927-9
> og læs den.
> Den siges iøvrigt også at være god for Java programmører, der skal skrive
> CORBA.
> I virkeligheden er der ikke særlig stor forskel på hvad der skal laves i
C++
> og Java.
>
> 2)
> Memory-håndtering i C++ er i sig selv ikke nødvendigvis simpelt, og CORBA
> gør det bestemt ikke nemmere.
>
> Jeg har haft meget gavn af at anvende Borland C++Builder
> Professional/Enterprise V5/V6 (www.borland.com) sammen C++ CORBA
> implementeringen TAO (http://www.cs.wustl.edu/~schmidt/TAO.html).
>
> C++Builder Professional/Enterprise har en feature, der hedder CodeGuard.
> CodeGuard checker effektivt en lang række typiske C og C++ fejl, såsom
> memory-leak, tilgang til frigivet memory, double delete, buffer over-run
> etc.
> CodeGuard finder også af og til fejl i ORB'en, selvom den er checket med
> Purify.
> For god ordens skyld: det er muligt at skrive en CORBA server eller klient
> med C++ uden at der er nogen former for fejl-rapporter fra CodeGuard. Man
> gør sig selv en stor tjeneste ved hele tiden at være i den tilstand.
>
> TAO er en open-source ORB, som umiddelbart kan oversættes med C++Builder.
> Hvis man oversætter såvel ORB'en som en egen applikation med CodeGuard
> enabled, giver det er vældigt godt check af den samlede applikation.
>
> Selv hvis man ikke ønsker at bruge TAO eller C++Builder til produktion, er
> kombinationen også _rigtig_ god til debug og uddannelsesformål.
>
>
> Venlig hilsen
>
> Mogens Hansen
>
>



Søg
Reklame
Statistik
Spørgsmål : 177558
Tips : 31968
Nyheder : 719565
Indlæg : 6408924
Brugere : 218888

Månedens bedste
Årets bedste
Sidste års bedste