Project

General

Profile

Actions

Feature #1944

closed

Bindings for C++ modules

Added by hazzadous over 15 years ago. Updated over 15 years ago.

Status:
Wontfix
Priority:
Normal
Category:
-
Target version:
-
ASK QUESTIONS IN Forums:

Description

Something similar to Apache's mod_cpp would be useful, and would certainly encourage me to write more lighty modules! I'll make a start. Msg me if your interested.


Files

plugin.hpp (4.26 KB) plugin.hpp hazzadous, 2009-04-02 11:38
plugin.hpp (4.26 KB) plugin.hpp Base classes and other definitions. hazzadous, 2009-04-02 15:34
mod_blank.hpp (548 Bytes) mod_blank.hpp Example null plugin header. hazzadous, 2009-04-02 15:34
mod_blank.cpp (194 Bytes) mod_blank.cpp Examplenull plugin implementation. hazzadous, 2009-04-02 15:34
plugin.hpp (6.75 KB) plugin.hpp Base classes and other definitions. hazzadous, 2009-04-02 15:36
plugin_cpp.cc (877 Bytes) plugin_cpp.cc peto, 2009-04-03 06:45
plugin_cpp.h (963 Bytes) plugin_cpp.h peto, 2009-04-03 06:45
mod_example.cc (460 Bytes) mod_example.cc peto, 2009-04-03 06:45

Related issues 1 (0 open1 closed)

Related to Feature #2067: base.h and http_req.h type namesWontfix2009-09-17Actions
Actions #1

Updated by peto over 15 years ago

There's no need for multiple APIs. Mostly, you should be able to just extern "C" your module_init, and the headers.

There are some C++ compatibility issues in 1.5, though: base.h declares member variables with the same name as a structure name. I'd recommend renaming struct http_req, request, physical, response and stat_cache (at least) to request_t, etc; although C allows this name aliasing, it's not a great thing to do.

Other than that, add AC_PROG_CXX to configure.in.

Actions #2

Updated by hazzadous over 15 years ago

Thanks for the info peto, I'll look into the base.h issues. I'm just looking at skeleton hpp, cpp's much like the mod_skeleton.c, and try to push as much shared functionality (ie. populating the plugin config) into a shared base. I'll have a look over the weekend.

Actions #3

Updated by hazzadous over 15 years ago

Attached is a start on a plugin.hpp . Just a play ground at the moment. I've not been thinking about optimisation yet, just getting an interface sorted.

Updated by hazzadous over 15 years ago

Done a little more. Added the start of a mod_blank plugin. Still have to get p->handle_* pointing correctly.

Actions #5

Updated by hazzadous over 15 years ago

Previous plugin.hpp was an incorrect version. New one there now. Also, forgot to make the setter functions templated.

Updated by peto over 15 years ago

Use the regular .h extension; almost nobody uses .hpp and it's unnecessary.

Don't use Boost. It's the home of some of the worst abuses and worst design in the C++ world, and for something this simple it's an unnecessary dependency.

Your editor is wrapping code
strangely.

I'm pretty sure you're overcomplicating this. Here's an example of something I think would work. It keeps the core concepts of the API the same, but avoids the unpleasant casting of the C interface and lets you expose your plugin as a class. The ABI it exports is identical. I didn't bother trying to get the rest of the headers to compile in C++, so I didn't even try to compile this, but the idea should be obvious.

This example is assuming C++ exceptions are turned off, which means new will return NULL on error rather than throwing. This is to guarantee that we won't throw an exception into the C code, where it'll abort. A better approach would be to catch all exceptions in the static functions and handle them appropriately, since you do need exceptions for production C++ code. I didn't write all of the interface functions, but you get the idea. It doesn't attempt to avoid setting plugin hooks that aren't used; they're all set, and it'll just use the default GO_ON handler.

Actions #7

Updated by stbuehler over 15 years ago

since you do need exceptions for production C++ code

I guess Trolltech disagrees... Qt is build without exceptions.

Actions #8

Updated by hazzadous over 15 years ago

Sure I'll use .h if you want. Using vim with 4 space tabs here. I'm using tabs as opposed to spaces for alignment, which could be the problem.

I'll use boost for now. It does what I want. I can remove dependencies later. If you can enlighten me as to your views on boost it would be most appreciated.

For some reason, I did not think of using p_d to identify the plugin object. This removes a lot from my plugin_base. I'm now sure how safe it is to be using pointers to static member functions.

The main reason for the complexity is that I wanted to hide as much as possible from derived plugins. So all that the plugin developer would need was to specify which handlers he has with the handlers typedef, and Plugin would deal at compile time, with the code to set the plugin data structure. Where as with your code, as you say, it would be setting all the handlers to run your virtual functions. I'm not sure how much of a performance hit this would have, or whether the compiler can optimise these calls out.

Other functions that are almost always there I have added as virtual functions. The set_defaults for instance. When I was looking at mod_lvhost, the set_defaults had a lot of boiler plate code, things that I wasn't interested in. This I was hoping would also be movable in to Plugin or plugin_base such that we need only specify the mappings "config-option" -> data member and their defaults either as data, or as a function of the other config options, and actual filling is done behind the scenes.

Mostly this is just me playing. If you think something like your example is more appropriate, I'm happy to go with that.

Actions #9

Updated by stbuehler over 15 years ago

static member functions are just normal function in a separate namespace.

and just as a sidenote: although we may fix C++ compatibility issues, i don't think we will add c++ code upstream; i recommend adding a wiki page with the details.

Actions #10

Updated by hazzadous over 15 years ago

Although it will work most of the time, really it should be an extern "C" free function. Depends on calling convention compatibilities.

Sure, no problems. I'll start a wiki page.

Actions #11

Updated by peto over 15 years ago

If you write C++ code like C--using malloc instead of new, and not using ctors--then you can get away without exceptions. But, try main() { while(1) new int102400; } with -fno-exceptions; it'll rudely abort() when it runs out of memory. (I had some recollection of new returning NULL on OOM when exceptions are disabled, but that's not what's happening.)

Much of Boost encourages template hell, which leads to bloated code that's hard to debug and usually hard to understand.

I'm sure the overhead of setting callbacks that you're not using will be miles below the noise floor.

The main reason for the complexity is that I wanted to hide as much as possible from derived plugins

But what you're really doing is creating an entirely new API. I don't think that's necessary--the existing API isn't complex at all, so all it's doing is making it harder for people using one API to understand code on the other, and creating a lot more work to maintain it over time, as the main API evolves.

Also, module authors are generally writing code that's tightly tied to the server itself: to figure out what's going on I usually need to trace back into the server code itself, to figure out how to make it do what I want. Having a complex layer standing between my code and the server makes that harder.

Although it will work most of the time, really it should be an extern "C" free function. Depends on calling convention compatibilities.

I'm fairly sure that you can't have different calling conventions for an extern "C" function and static member functions. That would imply that they aren't compatible types, and the compiler wouldn't allow the assignment in the first place; C++ is pretty strict about not performing questionable implicit casts, and I've never seen so much as a warning doing this. It would also imply that there's a way to declare "pointer-to-extern-C-function" vs. "pointer-to-static-member-function", but there isn't.

Actions #12

Updated by stbuehler over 15 years ago

I consider failed allocs always fatal, so i have no problem with abort(); and that is btw. exactly what glib is doing too.

Actions #13

Updated by stbuehler over 15 years ago

  • Tracker changed from Bug to Feature
Actions #14

Updated by stbuehler over 15 years ago

  • Status changed from New to Wontfix
  • Target version deleted (1.4.23)

I close this ticket now; if you have patches to fix compatibility issues for c++, i suggest you add them in a new ticket.

Actions #15

Updated by gstrauss 9 months ago

  • Related to Feature #2067: base.h and http_req.h type names added
Actions

Also available in: Atom