Archived
This forum has been archived. Please start a new discussion on GitHub.
can i create servant instance from shared library?help!
in Help Center
I tried to create servant instance from shared library like:
typedef Ice::Object* (*T_COMPONENT_FACTORY)();
...
IceInternal::DynamicLibraryPtr library
= new IceInternal::DynamicLibrary();
IceInternal::DynamicLibrary::symbol_type symbol
= library->loadEntryPoint(entryPoint, false);
T_COMPONENT_FACTORY factory = (T_COMPONENT_FACTORY)symbol;
Ice::ObjectPtr component = factory();
_adapter->add(component, Ice::stringToIdentity(identityStr));
but while the client calling the servant's method, it failed:
client:
.\TcpTransceiver.cpp:283: Ice::ConnectionLostException:
connection lost: WSAECONNRESET
server:
[ Service_D: Network: accepted tcp connection
local address = 10.10.10.75:10000
remote address = 10.10.10.75:2318 ]
Service_D: warning: connection exception:
.\ConnectionI.cpp:2133: Ice::UnknownException:
unknown exception:
unknown c++ exception
local address = 10.10.10.75:10000
remote address = 10.10.10.75:2318
[ Service_D: Network: closing tcp connection
local address = 10.10.10.75:10000
remote address = 10.10.10.75:2318 ]
can i do like this?! Thanks for your help!
typedef Ice::Object* (*T_COMPONENT_FACTORY)();
...
IceInternal::DynamicLibraryPtr library
= new IceInternal::DynamicLibrary();
IceInternal::DynamicLibrary::symbol_type symbol
= library->loadEntryPoint(entryPoint, false);
T_COMPONENT_FACTORY factory = (T_COMPONENT_FACTORY)symbol;
Ice::ObjectPtr component = factory();
_adapter->add(component, Ice::stringToIdentity(identityStr));
but while the client calling the servant's method, it failed:
client:
.\TcpTransceiver.cpp:283: Ice::ConnectionLostException:
connection lost: WSAECONNRESET
server:
[ Service_D: Network: accepted tcp connection
local address = 10.10.10.75:10000
remote address = 10.10.10.75:2318 ]
Service_D: warning: connection exception:
.\ConnectionI.cpp:2133: Ice::UnknownException:
unknown exception:
unknown c++ exception
local address = 10.10.10.75:10000
remote address = 10.10.10.75:2318
[ Service_D: Network: closing tcp connection
local address = 10.10.10.75:10000
remote address = 10.10.10.75:2318 ]
can i do like this?! Thanks for your help!
0
Comments
-
lanbo wrote:I tried to create servant instance from shared library like:
typedef Ice::Object* (*T_COMPONENT_FACTORY)();
...
IceInternal::DynamicLibraryPtr library
= new IceInternal::DynamicLibrary();
IceInternal::DynamicLibrary::symbol_type symbol
= library->loadEntryPoint(entryPoint, false);
T_COMPONENT_FACTORY factory = (T_COMPONENT_FACTORY)symbol;
Ice::ObjectPtr component = factory();
_adapter->add(component, Ice::stringToIdentity(identityStr));
but while the client calling the servant's method, it failed:
client:
.\TcpTransceiver.cpp:283: Ice::ConnectionLostException:
connection lost: WSAECONNRESET
server:
[ Service_D: Network: accepted tcp connection
local address = 10.10.10.75:10000
remote address = 10.10.10.75:2318 ]
Service_D: warning: connection exception:
.\ConnectionI.cpp:2133: Ice::UnknownException:
unknown exception:
unknown c++ exception
local address = 10.10.10.75:10000
remote address = 10.10.10.75:2318
[ Service_D: Network: closing tcp connection
local address = 10.10.10.75:10000
remote address = 10.10.10.75:2318 ]
can i do like this?! Thanks for your help!
It is certainly possible to do this, since this is essentially what IceBox does. The unknown c++ exception is most likely a translated structued exception (most likely an access violation). You can catch this easily enough in msdev. Go to Debug/Exceptions and then select Access Violation and select Action "Stop always". Then when your server dies you can determine what the problem is.
If you want some hints on how to implement this I would suggest looking at the IceBox source and IceBox demo.
Regards, Matthew0 -
Thanks matthew!0
-
There has a new problem , An unknown exception is thrown when the server running at this line(Incoming.cpp,line 175):
status = _servant->__dispatch(*this, _current);
What's the cause of the error?
server's log:
Service_D: warning: dispatch exception: unknown c++ exception
identity: hello
facet:
operation: ice_isA
[ Service_D: Network: closing tcp connection
local address = 10.10.10.75:10000
remote address = 10.10.10.75:4101 ]
client's log:
[ helloc: Network: tcp connection established
local address = 10.10.10.75:4101
remote address = 10.10.10.75:10000 ]
.\Outgoing.cpp:398: Ice::UnknownException:
unknown exception:
unknown c++ exception
[ helloc: Network: closing tcp connection
local address = 10.10.10.75:4101
remote address = 10.10.10.75:10000 ]
Thanks for your help!0 -
There are the debug values of the _servant's __vfptr:
- __vfptr 0x0137f658 const THello::`vftable' *
[0] 0x01371db0 THello::greet(const Ice::Current &) *
[1] 0xfffffffc *
[2] 0xfffffff0 *
[3] 0xfffffffc *
[4] 0x00000008 *
[5] 0x00000014 *
[6] 0x20646162 *
[7] 0x74736163 *
[8] 0x00000000 *
[9] 0x65746e49 *
[10] 0x636f6c72 *
[11] 0x4564656b *
[12] 0x61686378 *
[13] 0x4165676e *
[14] 0x26286464 *
[15] 0x6665725f *
They are differ from servant which is created and added to adapter in the static source code, such as:
Ice::ObjectPtr component = new THello();
_adapter->add(component, Ice::stringToIdentity(identityStr));
Why???0 -
I don't know why an unknown C++ exception would be raised from this code, it should work. The first thing you should do is to ensure that Ice, your DLL and executable are built with the same runtime library.
If your DLL and exe are linked with the ice.lib import library, you should compile them with /MD (release multi threaded). If they are linked with iced.lib, you should compile them with /MDd (debug multi threaded).
You could also take a look at the demo/IceBox/hello demo projects. I believe it's similar to what you're trying to do (the HelloI servant is compiled in the HelloService.dll and the DLL is loaded by the icebox executable).
Benoit.0 -
Thank benoit!
In IceBox, servant is created within the "service library"(such as HelloService.dll) as static source code like(suppose HelloService have several servants, such as HelloServant1, HelloServant2...):
--
Ice::ObjectPtr component1 = new THelloServant1();
_adapter->add(component1, Ice::stringToIdentity(identityStr1));
Ice::ObjectPtr component2 = new THelloServant2();
_adapter->add(component2, Ice::stringToIdentity(identityStr2));
...
--
Actually,I want to load "servant library" (such as HelloServant1.dll,HelloServant2.dll... but not HelloService.dll) in application process,which initialize service's Communicator and Adapter first.0 -
lanbo wrote:Thank benoit!
In IceBox, servant is created within the "service library"(such as HelloService.dll) as static source code like(suppose HelloService have several servants, such as HelloServant1, HelloServant2...):
--
Ice::ObjectPtr component1 = new THelloServant1();
_adapter->add(component1, Ice::stringToIdentity(identityStr1));
Ice::ObjectPtr component2 = new THelloServant2();
_adapter->add(component2, Ice::stringToIdentity(identityStr2));
...
--
Actually,I want to load "servant library" (such as HelloServant1.dll,HelloServant2.dll... but not HelloService.dll) in application process,which initialize service's Communicator and Adapter first.
The process is the same. If you need further assistance the best thing would be to create a self-contained compilable example that demonstrates the problem and we'd be glad to help.
Regards, Matthew0 -
matthew wrote:The process is the same. If you need further assistance the best thing would be to create a self-contained compilable example that demonstrates the problem and we'd be glad to help.
Regards, Matthew
The attachement is the whole example code, snippet from it:
// Mode 1: Usually, we do like this.
Ice::ObjectPtr hello1 = new THello();
adapter->add(hello1, Ice::stringToIdentity("hello1"));
IceInternal::DynamicLibraryPtr library
= new IceInternal::DynamicLibrary();
IceInternal::DynamicLibrary::symbol_type symbol
= library->loadEntryPoint("hellos:createHello", false);
T_COMPONENT_FACTORY factory = (T_COMPONENT_FACTORY)symbol;
// Mode 2: I don't want to convert type obvious,
// because I want it to be universal.
Ice::ObjectPtr hello2 = dynamic_cast<IHello*>(factory());
adapter->add(hello2, Ice::stringToIdentity("hello2"));
// Mode 3: It is what I want, but it run unsuccessfully:(
Ice::ObjectPtr hello3 = factory();
adapter->add(hello3, Ice::stringToIdentity("hello3"));
Thanks for your help!0 -
lanbo wrote:The attachement is the whole example code, snippet from it:
........
Thanks for your help!
You need to change the definition of createHello to
extern "C"
{
SCF_API Ice::Object* createHello()
{
return new THello;
}
}
After I did this your example worked nicely.
Best Regards, Matthew0 -
Aha, It's OK now!
A thousand thanks for Matthew's help!0