#233 Documentation: packing Quex lexer as DLL in VS

open
Martin Miller
5
2012-10-02
2012-02-03
Zhiqiang Zhang
No

When using visual studio, sometimes you may pack the Quex lexer in a dynamic link library (DLL).
So that other modules can use and the lexer.
Since visual studio requires you to declare the lexer as dllexport in order to make it available to be
used by other external modules, the lexer class should be declared as follows:
class declspec(dllexport) lexer {...};
And when using the class in an external module, the class should be declared as:
class
declspec(dllimport) lexer {...};

However, the lexer class generated by Quex has no dllexport or dll import attributes.
And there is no way to modify the lexer header file generated by Quex.
If you do nothing to this, then the linker will report "unresolved external symbol" error
when linking the lexer module with an external caller module.

A way to solve this is as follows:
First, if you are packing an DLL, it is common to define a macro DLL_EXPORT like this:

ifdef _DLL_EXPORT

#define DLL_EXPORT __declspec(dllexport)

else // _DLL_EXPORT

ifdef _DLL_IMPORT

#define DLL_EXPORT __declspec(dllimport)

else // _DLL_IMPORT

#define DLL_EXPORT

endif // _DLL_IMPORT

endif // _DLL_EXPORT

When you build the DLL module, define _DLL_EXPORT in the preprocessor defines (right click on project->Configuration Properties->C/C++->Preprocessor). Then DLL_EXPORT will be defined as __declspec(dllexport), and then the class or function
declared as DLL_EXPORT will be available for external linkage.

When you link the DLL module, define _DLL_IMPORT in the preprocessor defines. Then DLL_EXPORT will be defined as
__declspec(dllimport), and then the class or function declared as DLL_EXPORT will be imported from the DLL module.

The next step is a little tricky. Since the lexer class generated by Quex is not declared as dllexport or dllimport,
you have to do that in another way, not to edit the generated header file. What you need to do is to add the following
declarations in advance in the Quex header section:
header {
...
QUEX_NAMESPACE_MAIN_OPEN
class DLL_EXPORT lexer; // "lexer" is the Quex lexer class
class DLL_EXPORT Token; // optional, if the Token class is supposed to be available for external linkage
QUEX_NAMESPACE_MAIN_CLOSE
}

Discussion

  • ifdef WIN32

    if defined(__cplusplus_cli)

       using namespace System::Runtime::InteropServices;  // for 'DllImport'
    

    define DLL_EXPORT [DllImport("MyLexer.dll", CallingConvention = CallingConvention::Cdecl)]

    else

    define DLL_EXPORT __declspec(dllexport)

    endif

    else

    define DLL_EXPORT

    endif