Thread overview | |||||||
---|---|---|---|---|---|---|---|
|
January 23, 2016 Define "createXXX" functions for the constructors of class XXX | ||||
---|---|---|---|---|
| ||||
Hi all, While trying to interface C++ and D, I have to new a few D objects in C++ code. I am doing this using a D function: "XXX createXXX(...) { return new XXX(...); }". I am sure there must be some great way to automatically generate these creator functions, but I don't know how to do it. In the C++-header I will write manually: XXX* createXXX(int a, int b); XXX* createXXX(bool flag); In D source: extern (C++) class XXX { this(int a, int b) { /+...+/ } this(bool flag) { /+...+/ } } // Somehow define these guys automatically, "genCreateCtors!(XXX)" ? XXX createXXX(int a, int b) { return new XXX(a, b); } XXX createXXX(bool flag) { return new XXX(flag); } Thanks a lot! Johan |
January 23, 2016 Re: Define "createXXX" functions for the constructors of class XXX | ||||
---|---|---|---|---|
| ||||
Posted in reply to Johan Engelen | On Saturday, 23 January 2016 at 19:42:29 UTC, Johan Engelen wrote: > Hi all, > While trying to interface C++ and D, I have to new a few D objects in C++ code. I am doing this using a D function: "XXX createXXX(...) { return new XXX(...); }". > I am sure there must be some great way to automatically generate these creator functions, but I don't know how to do it. > > In the C++-header I will write manually: > XXX* createXXX(int a, int b); > XXX* createXXX(bool flag); > > In D source: > extern (C++) class XXX { > this(int a, int b) { /+...+/ } > this(bool flag) { /+...+/ } > } > > // Somehow define these guys automatically, "genCreateCtors!(XXX)" ? > XXX createXXX(int a, int b) { return new XXX(a, b); } > XXX createXXX(bool flag) { return new XXX(flag); } > > Thanks a lot! > Johan Wow! There are lots of XXX there. Anyway, I did a similar thing to yours for automatic attribute definition before. Three things: 1. Template 2. Mixin 3. Compile time function You define a compile time function which generates a string that is valid D code. You define template that takes some parameters (Your XXX values), and calls the function to merge them. In your class, you use mixin and template to generate the string and inject the generated code. Not that complex once you do it. Try to understand this code. http://david.rothlis.net/d/templates/ Its in there. |
January 23, 2016 Re: Define "createXXX" functions for the constructors of class XXX | ||||
---|---|---|---|---|
| ||||
Posted in reply to Johan Engelen | On Sat, 23 Jan 2016 19:42:29 +0000, Johan Engelen wrote: > // Somehow define these guys automatically, "genCreateCtors!(XXX)" ? > XXX createXXX(int a, int b) { return new XXX(a, b); } > XXX createXXX(bool flag) { return new XXX(flag); } Check out http://dpaste.dzfl.pl/430dabf25935 I used string mixins to be absolutely, 100% sure that the right things ended up in the symbol table. __traits(getOverloads, Type, "name") gets function overloads for the given name. It gets them as an AliasSeq, which presents an array-like interface. Constructors use the name "__ctor". So you can get all constructors for a class named MyClass with: __traits(getOverloads, MyClass, "__ctor") This only includes explicitly defined constructors, not the default constructor, so we handle that separately. std.traits defines a Parameters template that takes a function and yields a parameter type tuple. We can hand it a constructor and it does the right thing. We can treat a bunch of values as one value if their type is a type tuple, so that's exactly what we do. Then it's just a bit of string manipulation to get the right class names and overloads in the right places and we've generated a string of D code that does what we want. Mix it in and Bob's your uncle. In your code, the line mixin(factory!MyClass); should be inside an extern(C++) block, naturally. The major caveat there: wherever you call "mixin(factory!MyClass);", you need MyClass to be in scope directly. If you have to refer to it with a qualified name, this will break. If that causes problems for you, you can use: extern(C++) { { import mypkg.mymodule : MyClass; mixin(factory!MyClass); } } And that should import just that class for just that one block of code. |
January 24, 2016 Re: Define "createXXX" functions for the constructors of class XXX | ||||
---|---|---|---|---|
| ||||
Posted in reply to Chris Wright | Thanks for the rapid explanations and code! Such a great forum :-) Much obliged, Johan |
January 24, 2016 Re: Define "createXXX" functions for the constructors of class XXX | ||||
---|---|---|---|---|
| ||||
Posted in reply to Johan Engelen | On Saturday, 23 January 2016 at 19:42:29 UTC, Johan Engelen wrote:
> Hi all,
> While trying to interface C++ and D, I have to new a few D objects in C++ code. I am doing this using a D function: "XXX createXXX(...) { return new XXX(...); }".
An easier way for trivial constructors (note parents!), is to also define the constructor inline in C++ header.
in .d:
extern (C++) class Klass {
int b;
this(int a) { b = a+1; }
}
in .h:
class Klass {
int b;
Klass(int a) { b = a+1; }
};
It's what DDMD does in a few cases.
|
Copyright © 1999-2021 by the D Language Foundation