Thread overview
Reuse C memory for D struct?
Nov 21, 2013
Lemonfiend
Nov 21, 2013
evilrat
Nov 21, 2013
Lemonfiend
Nov 21, 2013
Ali Çehreli
Nov 25, 2013
Lemonfiend
Nov 25, 2013
Dicebot
Nov 25, 2013
Lemonfiend
Nov 22, 2013
Mike Parker
Nov 23, 2013
Baz
Nov 23, 2013
evilrat
November 21, 2013
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
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
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
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
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
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
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
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
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
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!