Thread overview | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
|
November 21, 2013 Reuse C memory for D struct? | ||||
---|---|---|---|---|
| ||||
Hi! I'm wondering if it's possible to have a struct in D which uses the same pointer and memory as returned by the extern C function. This would allow me to manipulate and use the C struct directly in D code. I'm not sure how to better explain this, hopefully the following pseudocode clarifies my question struct Tree { enum treeSize = 40; ubyte[treeSize] _this; this(int apples) { // use the C provided pointer somehow? // neither of the following seem to do the trick //this = *cppNew(apples); //_this = *cast(ubyte*)cppNew(apples) } Tree* cppNew(int apples) { // calls extern C constructor which returns a pointer to a Tree of size treeSize } ~this() { cppDelete(); } void cppDelete() { // this needs the pointer returned by cppNew to do an extern C delete } } void main() { Tree tree = Tree(12); } |
November 21, 2013 Re: Reuse C memory for D struct? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Lemonfiend | On Thursday, 21 November 2013 at 15:22:10 UTC, Lemonfiend wrote:
> Hi!
>
> I'm wondering if it's possible to have a struct in D which uses the same pointer and memory as returned by the extern C function.
> This would allow me to manipulate and use the C struct directly in D code.
so what really stops you from accessing that pointer in D?
if you fear for data layout just wrap this pointer in D struct and give properties to accessing stuff from pointer(weird)
|
November 21, 2013 Re: Reuse C memory for D struct? | ||||
---|---|---|---|---|
| ||||
Posted in reply to evilrat | On Thursday, 21 November 2013 at 17:12:26 UTC, evilrat wrote: > On Thursday, 21 November 2013 at 15:22:10 UTC, Lemonfiend wrote: >> Hi! >> >> I'm wondering if it's possible to have a struct in D which uses the same pointer and memory as returned by the extern C function. >> This would allow me to manipulate and use the C struct directly in D code. > > so what really stops you from accessing that pointer in D? Well right now, in the code above, the original C pointer is lost, only the D pointer remains. > if you fear for data layout just wrap this pointer in D struct and give properties to accessing stuff from pointer(weird) Yes a solution would be to simply store the C pointer in the D struct, but then the C and D structs are no longer the same. |
November 21, 2013 Re: Reuse C memory for D struct? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Lemonfiend | On 11/21/2013 07:22 AM, Lemonfiend wrote: > I'm wondering if it's possible to have a struct in D which uses the same > pointer and memory as returned by the extern C function. > This would allow me to manipulate and use the C struct directly in D code. > > I'm not sure how to better explain this, hopefully the following > pseudocode clarifies my question > > struct Tree > { > enum treeSize = 40; > > ubyte[treeSize] _this; > > this(int apples) > { > // use the C provided pointer somehow? > // neither of the following seem to do the trick > //this = *cppNew(apples); > //_this = *cast(ubyte*)cppNew(apples) If you instead maintain a slice of Apples and assuming that 'apples' is the number of apples, then you can use the following syntax Apple[] _this; // ... _this = cppNew[0 .. apples]; I have some information about that syntax under the "Producing a slice from a pointer" section here: http://ddili.org/ders/d.en/pointers.html One thing that is not mentioned in there is that you are still responsible for the Apples that are returned by the C library. Ali |
November 22, 2013 Re: Reuse C memory for D struct? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Lemonfiend | On 11/22/2013 12:22 AM, Lemonfiend wrote:
> Hi!
>
> I'm wondering if it's possible to have a struct in D which uses the same
> pointer and memory as returned by the extern C function.
> This would allow me to manipulate and use the C struct directly in D code.
I'm trying to understand why you would want to this, but I just can't see a reason. Why not just define a struct in D that matches the C definition and then use the pointer directly?
Example:
// foo.h
typedef struct {
int x;
} Foo;
extern Foo* newFoo( void );
// foo.d
struct Foo {
int x;
}
extern( C ) Foo* newFoo();
auto f = newFoo();
writeln( f.x );
Of course, if Foo is an opaque struct on the C side, you'll be playing with fire if you define it in D and don't have control of the C library. In that case, you should make it opaque in D as well.
|
November 23, 2013 Re: Reuse C memory for D struct? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Lemonfiend | On Thursday, 21 November 2013 at 15:22:10 UTC, Lemonfiend wrote:
> Hi!
>
> I'm wondering if it's possible to have a struct in D which uses the same pointer and memory as returned by the extern C function.
> This would allow me to manipulate and use the C struct directly in D code.
>
> I'm not sure how to better explain this, hopefully the following pseudocode clarifies my question
>
> struct Tree
> {
> enum treeSize = 40;
>
> ubyte[treeSize] _this;
>
> this(int apples)
> {
> // use the C provided pointer somehow?
> // neither of the following seem to do the trick
> //this = *cppNew(apples);
> //_this = *cast(ubyte*)cppNew(apples)
> }
>
> Tree* cppNew(int apples)
> {
> // calls extern C constructor which returns a pointer to a Tree of size treeSize
> }
>
> ~this()
> {
> cppDelete();
> }
>
> void cppDelete()
> {
> // this needs the pointer returned by cppNew to do an extern C delete
> }
> }
>
> void main()
> {
> Tree tree = Tree(12);
> }
if your D struct is POD and alocated on the heap, it's the same, as long as data type are the same and not plateform-dependent.I'm mean that that you just cast from the initial pointer...
|
November 23, 2013 Re: Reuse C memory for D struct? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Baz | On Saturday, 23 November 2013 at 01:39:00 UTC, Baz wrote:
>
> if your D struct is POD and alocated on the heap, it's the same, as long as data type are the same and not plateform-dependent.I'm mean that that you just cast from the initial pointer...
and because of D UFCS it is possible to have methods for this struct lying in module scope, not struct :)
|
November 25, 2013 Re: Reuse C memory for D struct? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | On Thursday, 21 November 2013 at 19:21:10 UTC, Ali Çehreli wrote:
> On 11/21/2013 07:22 AM, Lemonfiend wrote:
>
> > I'm wondering if it's possible to have a struct in D which
> uses the same
> > pointer and memory as returned by the extern C function.
> > This would allow me to manipulate and use the C struct
> directly in D code.
> >
> > I'm not sure how to better explain this, hopefully the
> following
> > pseudocode clarifies my question
> >
> > struct Tree
> > {
> > enum treeSize = 40;
> >
> > ubyte[treeSize] _this;
> >
> > this(int apples)
> > {
> > // use the C provided pointer somehow?
> > // neither of the following seem to do the trick
> > //this = *cppNew(apples);
> > //_this = *cast(ubyte*)cppNew(apples)
>
> If you instead maintain a slice of Apples and assuming that 'apples' is the number of apples, then you can use the following syntax
>
> Apple[] _this;
>
> // ...
>
> _this = cppNew[0 .. apples];
>
> I have some information about that syntax under the "Producing a slice from a pointer" section here:
>
> http://ddili.org/ders/d.en/pointers.html
>
> One thing that is not mentioned in there is that you are still responsible for the Apples that are returned by the C library.
>
> Ali
I had previously attempted this, but without success.
So I decided to give it another try your way.
Slicing is tricky!
ubyte[] _this;
vs
ubyte[size] _this;
and
_this = cPointer[0 .. size];
vs
_this[] = cPointer[0 .. size];
After trying all variations, it still didn't work.
Then a colleague noticed I was checking the results with:
&_this
vs
_this.ptr
I had thought those would give the same result, but apparently not?
So in the end it worked:
ubyte[] _this;
_this = cPointer[0 .. size];
_this.ptr == cPointer: true
Thanks! (and apologies for the late reply)
|
November 25, 2013 Re: Reuse C memory for D struct? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Lemonfiend | On Monday, 25 November 2013 at 17:38:00 UTC, Lemonfiend wrote:
> &_this
> vs
> _this.ptr
>
> I had thought those would give the same result, but apparently not?
Think about slice as a struct with two fields - data pointer and data length. `&slice` gives pointer to struct itself, `slice.ptr` yields data pointer.
|
November 25, 2013 Re: Reuse C memory for D struct? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dicebot | On Monday, 25 November 2013 at 17:57:21 UTC, Dicebot wrote:
> On Monday, 25 November 2013 at 17:38:00 UTC, Lemonfiend wrote:
>> &_this
>> vs
>> _this.ptr
>>
>> I had thought those would give the same result, but apparently not?
>
> Think about slice as a struct with two fields - data pointer and data length. `&slice` gives pointer to struct itself, `slice.ptr` yields data pointer.
That's very clear, thanks!
|
Copyright © 1999-2021 by the D Language Foundation