www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Reuse C memory for D struct?

reply "Lemonfiend" <lemon fie.nd> writes:
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);
}
Nov 21 2013
next sibling parent reply "evilrat" <evilrat666 gmail.com> writes:
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)
Nov 21 2013
parent "Lemonfiend" <lemon fie.nd> writes:
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.
Nov 21 2013
prev sibling next sibling parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
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
Nov 21 2013
parent reply "Lemonfiend" <lemon fie.nd> writes:
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)
Nov 25 2013
parent reply "Dicebot" <public dicebot.lv> writes:
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.
Nov 25 2013
parent "Lemonfiend" <lemon fie.nd> writes:
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!
Nov 25 2013
prev sibling next sibling parent Mike Parker <aldacron gmail.com> writes:
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.
Nov 21 2013
prev sibling parent reply "Baz" <bburg.basile yahoo.fr> writes:
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...
Nov 22 2013
parent "evilrat" <evilrat666 gmail.com> writes:
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 :)
Nov 22 2013