質問

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.

役に立ちましたか?

解決

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!

他のヒント

Quick Answer

Abandon the idea of building user-mode components with DDK tools (although I find the concept fascinating :-P)

Your kernel mode component should be built separately from the user mode components as a matter of good practice.

Vague thoughts

Off the top of my head, and this really speaking from limited experience...there are a lot of subtle differences that can creep up if you try to mix the two together.

Using your own example of __cdecl vs __stdcall; You have two different calling conventions. _cdecl is all kernel stuff and all of the C++ methods are wrapped around in WINAPI (_stdcall) passing conventions and __stdcall will clean do auto stack clean up and expect frame pointers inserted all over the place. And if you by accident use compiler options to trigger a __fastcall, it would be a pain to debug.

You can definitely hack something together, but do you really want to keep track of that in your user-space code and build environment? UGH I say.

Unless you have very specific engineering reasons to mix the two environments, (and no a unified build experience is not a valid reason, because you can get that from a batch file called buildall.bat) I say use the separate toolchains.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top