Windows System Software -- Consulting, Training, Development -- Unique Expertise, Guaranteed Results
The free OSR Learning Library has more than 50 articles on a wide variety of topics about writing and debugging device drivers and Minifilters. From introductory level to advanced. All the articles have been recently reviewed and updated, and are written using the clear and definitive style you've come to expect from OSR over the years.
Check out The OSR Learning Library at: https://www.osr.com/osr-learning-library/
I understand that this question has been asked repeatedly, but...How are things now with writing C++ code in drivers?
Is it possible to write polymorphic classes, use destructors and class constructors?
I am interested in writing basic things in C++: polymorphism, inheritance, etc.
Thanks!
Upcoming OSR Seminars | ||
---|---|---|
OSR has suspended in-person seminars due to the Covid-19 outbreak. But, don't miss your training! Attend via the internet instead! | ||
Writing WDF Drivers | 7 Dec 2020 | LIVE ONLINE |
Internals & Software Drivers | 25 Jan 2021 | LIVE ONLINE |
Developing Minifilters | 8 March 2021 | LIVE ONLINE |
Comments
of course you can use C++ for your project, its can do all your things. btw, manage your objects, classes, resources in ctor and dtor carefully, its might cause the system to crash or memory leaks.
No C++ exceptions... use placement new... be careful of your stack usage particularly passing method arguments (pass by ref is your friend in good C++ in any case).
Good to go,
Peter
Peter Viscarola
OSR
@OSRDrivers
Here we go.....
My -2,000,000,000 cents: of course you can. See KMDF source code on github.
Mark Roddy
All of those things have actually been possible since the 20th Century. AVStream drivers have been written in C++ since Windows 2000, with constructors and destructors. The only change is that it is now officially blessed.
Tim Roberts, [email protected]
Providenza & Boekelheide, Inc.
Tnx, guys!
And what about using stl/boost - only proble in C++ exceptions?
I absolutely can't use these libraries?
Well, I did say “ No C++ exceptions” ... so, that would mean STL and boost are not allowed. As well as a significant amount of std, more importantly.
But you can used ranged for loops! Are you excited now? ;-)
Peter
Peter Viscarola
OSR
@OSRDrivers
Well... No. Maybe. Several people, somewhere, have tried to do this. There was even a reasonably complete implementation by... Google maybe? I can't remember. It was ancient. But, basically, it comes down to "no." Would you want to stake your driver's correctness on some shite put together by some random organization?
In the bigger picture, who cares about the STL, specifically, anyways in 2020? It's mostly been supplanted by std. But, no matter, you can't use any of the std functions that raise, either.
So, RAII... good to go. UNIQUE_PTR... good to go. std::vector? Ain't happenin'.
Peter
Peter Viscarola
OSR
@OSRDrivers
Yes, but very limited in practice since the standard containers are mostly not usable. A container that is perfect for kernel development and range based for statements is std::array, which is a better, safer C array and is exception free. But as the header files bundled with the WDK are so ancient there is no std:array with them. But one can always make their own custom containers and allow use of range based for statements on them.
And this is precisely what I hate about the "kernel C++" subject. For any C++ construct, I have to stop reading and think, is this allowed?
What dirty magic trick can do this thing under the covers? (calling code? allocation? placing stuff in wrong section?)
(Maybe an automated verification tool could help here...)
So far, kernel C++ is not helping save time for code reviews, hampers readability, and without most of powerful library stuff and coding patterns based on that stuff, it is pointless.
Only one thing makes me jealous about c++: template and constexpr tricks that allow folding strings and complex expressions at compile time.
I did encounter a "C++ exceptions in the kernel" library written by one of the major former luminaries in this field. It did some very ... um ... unorthodox things. I set it down and backed away slowly.
Tim Roberts, [email protected]
Providenza & Boekelheide, Inc.
It’s documented to raise an exceptions. No C++ exceptions in the kernel. Hence no std::vector.
Peter
Peter Viscarola
OSR
@OSRDrivers
It works for plain arrays... so, at least there’s that.
C++ is confusing, ugly, and so overwrought with features it is ridiculous. And... I admit, C++ is probably the world’s second worst system implementation language... THE worst is, of course, C.
That sounds like a statement from somebody who has not much tried using it, within some reasonable bounds.
Strong type checking, by itself, is sufficient reason to write your code in pretty much standard C and add a .cpp file type.
Also,”constexpr” is undoubtedly an improvement over #define, and we use it this way as much as possible.
There are some very good cases for using std::unique_ptr as well, and (in general) RAII classes that “automatically destruct” when they go out of scope. It’s not something I use in every driver that I write, but — given that I firmly believe try/finally is an evil construct — when I have something that needs allocation, initialization, use, and then some complex destruction at the end of the function... it can be super handy. The challenge to this in a driver that is otherwise pretty much normal C is writing enough in-line documentation to prevent future maintainers from going nuts. There’s also the problem of one person’s “it would be tidy to make an RAII class of this here” is another person’s “I can’t believe they added all this shite and made the code more complex! Just clean-up properly at the end of the function!”
It’s OK... we’ll all be writing drivers in Rust soon, so we won’t have to have this debate much longer. (Picture me rolling my eyes and shaking my head as you read that last sentence... Its meant to be a joke, not an insider hint.)
Peter
Peter Viscarola
OSR
@OSRDrivers
No matter what you do, you're left with problems like this:
std::vector x;
x.insert(x.end(), 1);
x.insert(x.end(), 2);
int y = x[9];
There's no way to return anything to signal an error there. It all still
ends in abort() or thereabouts.
mm
I think that'd be a great project for you to undertake.
When you get that done, please be sure to post back here and let us know how it all turned out.
Peter
Peter Viscarola
OSR
@OSRDrivers
There are implementations of STL that do not throw exceptions, and rumor has it they can be used in the kernel. I've always been a little wary of those; STL tends to be pretty free with memory, and memory churn in a driver is undesirable.
Tim Roberts, [email protected]
Providenza & Boekelheide, Inc.
Yes, Rust. The new Microsoft's toy. As it already has become a tradition, others look where Microsoft goes, then rush in the opposite direction.
The same will happen with Rust, mind my word.
-- pa
@mm About your example - C++ language exceptions are very different from "asynchronous" exceptions, aka signals. The latter generally may occur when the program state is corrupted (like memory overwrite) so should not be recovered by a language exception handler. So it's not a good example here.
-- pa
Oh wow, I didn't know that. Cool.
Mr. Funky... please. Stop. Think.
You can’t predict what will raise. vector::push_back can raise. Without that, why use std::vector?
So... let’s just leave it at “You can’t use anything that can possibly raise.” OK?
Peter
Peter Viscarola
OSR
@OSRDrivers
Seriously? Do you actually program in C++ or is this something you’re thinking about starting?
OK... the answer: You read the documentation. If a method can raise, it’ll be documented. Because, if it’s not documented to raise, you can’t be ready to catch the exception, right?
Peter
Peter Viscarola
OSR
@OSRDrivers
Remember, even if you never TRIGGER an exception, the mere fact that a function includes code to throw an exception means that it has to call run-time library routines to set things up. Those runtime library routines are not present in the kernel run-time. So, it's not that "you can't throw an exception", it's that "you can't compile any code that MIGHT throw an exception."
Tim Roberts, [email protected]
Providenza & Boekelheide, Inc.
There are inofficial runtime implementations of the support for exceptions in drivers like https://github.com/avakar/vcrtl
This cyclic discussion has (d)evolved from:
"NO NEVER!" vs "Its OK, with caveats"
To:
"It's OK with documented limitations" vs "But I need stdlib this or stdlib that"
I guess that is progress.
Well, like so many other discussions... on the climate, or the damned virus, or possibilty that modern humans have genes of Neanderthals
-- pa
And another question: C++17 standard in Visual Studio for kernel drivers are enabled with /kernel flag?