Archived

This forum has been archived. Please start a new discussion on GitHub.

LoadLibrary from an IceBox service

Hi,

I'm trying to load a dll in the start() method of a c++ icebox service. It seems like the dll gets loaded fine.

Here's the start() method
void GameSvc::start(const string &name,
                            const Ice::CommunicatorPtr &communicator,
                            const Ice::StringSeq &)
{
    m_comm = communicator;
    m_logger = communicator->getLogger();
    m_logger->trace(__FILE__, "starting...");

    themeId = m_comm->getProperties()->getProperty("GameService.Theme.Id");
    m_logger->trace(__FILE__, "ThemeId: " + themeId);

    gameModule = LoadLibrary(TEXT("C:\\ws\\webplatform_onlineGE\\webplatform\\applications\\EgyptianRiches\\server\\Debug\\EgyptianRiches.dll"));
    if (!gameModule)
    {
        stringstream errStream;
        DWORD errCode = GetLastError();
        errStream << "Failed to load game dll: " + themeId << ", errCode: " << errCode;
        m_logger->error(errStream.str());
    }
    m_logger->trace(__FILE__, "dll loaded");

    TEST proc = (TEST)GetProcAddress(gameModule, "test");
    if (proc)
    {
        m_logger->trace(__FILE__, "calling dll function");
        (proc)();
        m_logger->trace(__FILE__, "done calling dll function");
    }
}

the dll's DllMain entry point does a cout everytime it's called. It also has test() function that gets called from the IceBox server. All the test function does is a cout. Here's the dll code
BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
					 )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        cout << "Process ATTACHED" << endl;
        break;
    case DLL_THREAD_ATTACH:
        cout << "Thread ATTACHED" << endl;
        break;
    case DLL_THREAD_DETACH:
        cout << "Thread DETTACHED" << endl;
        break;
    case DLL_PROCESS_DETACH:
        cout << "Process DETACHED" << endl;
        break;
    }
    return TRUE;
}

extern "C" __declspec(dllexport) void test()
{
    cout << "Test called" << endl;
}

I'm trying to understand how the following output is produced.
Process ATTACHED
Thread ATTACHED
Test called
Thread ATTACHED
Svc.cpp: starting...
-- 01/06/11 16:42:14.564 CIceBoxGameServer1-GameService: src\GameSvc.cpp: ThemeId: EgyptianRiches
-- 01/06/11 16:42:14.564 CIceBoxGameServer1-GameService: src\GameSvc.cpp: dll loaded
-- 01/06/11 16:42:14.564 CIceBoxGameServer1-GameService: src\GameSvc.cpp: calling dll function
-- 01/06/11 16:42:14.564 CIceBoxGameServer1-GameService: src\GameSvc.cpp: done calling dll function

It seems like the logs are printed out of order in the IceBox server stdout.

I would have expected the following. I'm also not sure why the DLLMain entry point is called twice with DLL_THREAD_ATTACH reason code.
Svc.cpp: starting...
Process ATTACHED
Thread ATTACHED
Thread ATTACHED
-- 01/06/11 16:42:14.564 CIceBoxGameServer1-GameService: src\GameSvc.cpp: ThemeId: EgyptianRiches
-- 01/06/11 16:42:14.564 CIceBoxGameServer1-GameService: src\GameSvc.cpp: dll loaded
-- 01/06/11 16:42:14.564 CIceBoxGameServer1-GameService: src\GameSvc.cpp: calling dll function
Test called
-- 01/06/11 16:42:14.564 CIceBoxGameServer1-GameService: src\GameSvc.cpp: done calling dll function

Thanks
Budyanto

Comments

  • benoit
    benoit Rennes, France
    Hi,

    The default Ice logger uses "cerr" for its output. Can you try using cerr instead of cout and see if it prints the statements in the expected order?

    The 2 thread attach entry point calls are perhaps caused by the startup of the communicator threads in the background. Are you using a communicator per IceBox service? As an experiment, I would try adding sleep before loading the DLL and see if you still get or not those calls.

    Cheers,
    Benoit.
  • Thanks...changing cout to cerr give me what I expected. So it's just a matter of using different output streams.