Search code examples
c++cwindowskernelwdk

Including C++ headers in user mode programs built with NT DDK


So...I have a kernel mode component and a user mode component I'm putting together using the turnkey build environment of the NT DDK 7.1.0. The kernel component is all .c/.h/.rc files. The user mode component is .cpp/.c/.h/.rc files.

At first it seemed simplest to use build for both, as I saw you could modify the ./sources file of the user mode component to say something like:

TARGETNAME = MyUserModeComponent
TARGETTYPE = PROGRAM
UMTYPE = windows
UMENTRY = winmain
USE_MSVCRT = 1

That didn't seem to cause a problem and so I was pleased, until I tried to #include <string> (or <memory>, or whatever) Doesn't find that stuff:

error C1083: Cannot open include file: 'string': No such file or directory

Still, it's compiling the user mode piece with C++ language semantics. But how do I get the standard includes to work?

I don't technically need to use the DDK build tool for the user mode piece. I could make a visual studio solution. I'm a bit wary as I have bumped into other annoyances, like the fact that the DDK uses __stdcall instead of __cdecl by default... and there isn't any pragma or compiler switch to override this. You literally have to go into each declaration you care about and change it, assuming you have source to do so. :-/

I'm starting to wonder if this is just a fractal descent into "just because you CAN doesn't mean you SHOULD build user mode apps with the DDK. Here be dragons." So my question isn't just about this particular technical hurdle, but rather if I should abandon the idea of building a C++ user mode component with the DDK tools...just because the kernel component is pure C.


Solution

  • To build a user mode program with WINDDK you need to add some variables to your SOURCES file:

    • 386_STDCALL=0 to use cdecl calling convention by default
    • USE_STL=1 to use STL
    • USE_NATIVE_EH=1 to add a support for exception handling

    Everything else you already have.

    I'll put my full SOURCES file for reference:

    TARGETNAME = MyUserModeComponent
    TARGETTYPE = PROGRAM
    TARGETPATH = obj
    UMTYPE = console
    UMENTRY = main
    
    USE_MSVCRT = 1
    USE_NATIVE_EH=1
    USE_STL=1
    386_STDCALL=0
    
    SOURCES= main.cpp
    

    And main.cpp:

    #include <iostream>
    #include <string>
    
    using namespace std;
    
    int main()
    {
        string s = "bla bla bla!";
        cout << s;
    
        return 0;
    }
    

    Have fun!