Learn how easy it is to sync an existing GitHub or Google Code repo to a SourceForge project! See Demo

Close

#1037 Lexers are missing in lexerCatalogue vector

Bug
closed-works-for-me
Neil Hodgson
Scintilla (790)
3
2011-11-01
2010-09-26
Anonymous
No

In the file 'Catalogue.cxx' (Scintilla version 2.21), there is a std::vector 'lexerCatalogue'. It becomes initialized after 'Scintilla_LinkLexers' has added the lexers. The vector is empty afterwards. I use VS2005 and have changed SciLexer.vcproj to build a static library that is linked into my application. I also use the MFC wrapper made by PJ Naughter (version 1.25, it was updated with ConvertScintillaiface.js). I used the workaround described below.

Replaced:
static std::vector<LexerModule *> lexerCatalogue;

With:
static std::vector<LexerModule *>& GetLexerCatalogue()
{
static std::vector<LexerModule *> lc;
return lc;
}
#define lexerCatalogue GetLexerCatalogue()

Discussion

  • Neil Hodgson
    Neil Hodgson
    2010-09-27

    I don't understand why the vector is empty 'afterwards'. If you mean after calling Scintilla_LinkLexers then I don't understand what is emptying the vector. Nothing is deleted from this vector until the module is unloaded.

     
  • Neil Hodgson
    Neil Hodgson
    2010-09-27

    • assigned_to: nobody --> nyamatongwe
    • priority: 5 --> 3
    • status: open --> open-works-for-me
     
  • Jeff Laing
    Jeff Laing
    2010-10-04

    I have had a similar problem compiling Scintilla into my own DLL.

    For me, the problem is that Scintilla provides its own DllMain function which prevents the C++ runtime library from initialising all the static Lexer objects. Each object has its 'language' field initialised to zero (because the memory is allocated, but the constructor has not been run) and because its zero, Lexer::Find() never returns it.

    The fix was to call _CRT_INIT in DllMain() - here is what I used.

    // Since the lexers are implemented as static C++ objects, we need to ensure
    // that the C++ runtime is loaded. That means calling a special runtime
    // initialisation routine, if you want to be a dynamically loaded DLL.
    //
    // See http://support.microsoft.com/kb/94248 for more (though not much :-( )
    //
    // The prototype for _CRT_INIT is available in a special header, though you
    // need a magic #define as well
    //
    #define _DECL_DLLMAIN
    #include <process.h>

    // The standard release of Scintilla has the prototype of DllMain wrong, which
    // the inclusion of <process.h> then complains about.
    // extern "C" BOOL APIENTRY DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpv) {
    extern "C" BOOL WINAPI DllMain(HANDLE hInstance, DWORD dwReason, LPVOID lpv) {
    // Platform::DebugPrintf("Scintilla::DllMain %d %d\n", hInstance, dwReason);
    if (dwReason == DLL_PROCESS_ATTACH) {
    _CRT_INIT(hInstance,dwReason,lpv);
    if (!Scintilla_RegisterClasses(hInstance))
    return FALSE;
    } else if (dwReason == DLL_PROCESS_DETACH) {
    Scintilla_ReleaseResources();
    _CRT_INIT(hInstance,dwReason,lpv);
    }
    return TRUE;
    }

     
  • Neil Hodgson
    Neil Hodgson
    2010-10-05

    If you want to use your own DllMain then this is similar to linking into an executable so you should define STATIC_BUILD so that Scintilla's DllMain is not compiled.

     
  • Neil Hodgson
    Neil Hodgson
    2011-11-01

    • status: open-works-for-me --> closed-works-for-me