how to pass a ubyte[] to c interface?

zhmt via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Fri Mar 13 00:16:38 PDT 2015


On Friday, 13 March 2015 at 06:56:33 UTC, Ali Çehreli wrote:
> On 03/12/2015 11:35 PM, zhmt wrote:
>
> > ubyte[] arr ;
> >
> > I pass the arr.ptr to c program
>
> Unless there is sentinel value at the end of the array, you 
> must also pass the number of elements (as Rikki Cattermole has 
> shown).
>
> However, if the C function holds on to that pointer for later 
> use, you must also keep the array alive. You can ensure that by 
> two general ways:
>
> a) The D-side slice must not be a local slice. For example, it 
> can be a member of a long-living object or it is a module-scope 
> variable.
>
> b) Tell the garbage collector that there is indeed a reference 
> to that memory block somewhere else (even though there is no 
> D-side reference to it). You can do this with GC.addRoot. (The 
> opposite function is GC.removeRoot.)
>
> >, it fails silently.
>
> That's not good.
>
> > Is there any way to cast a ubyte[] to a clang pointer?
>
> Going off-topic, I think you mean the C language when you say 
> "clang", which may be confusing because there is also the 
> compiler called clang. :)
>
> Ali


sorry for "clang", I mean c , not clang of mac.

Thanks for you advice, I use coroutine, so the array will hold in 
stack, will not be gc before return.

And I successfully passed the arr.ptr to c program. I found the 
root of problem:
The order of method declaration in c++ class and d interface must 
be exactly the same:

this is d code:

         interface CConn
	 {
		void free();
		int connect(ubyte* ip,int port,CFiberCtx fiberctx);
		int read(ubyte* buf,int offset, int len,CFiberCtx fiberctx);
		int readSome(ubyte* buf,int offset, int len,CFiberCtx fiberctx);
		int write(ubyte* buf,int offset, int len,CFiberCtx fiberctx);
	}

this is c++ class:

class CConn
{
public:
   //==== dlang interfaces;
   virtual void free();
   virtual int connect(char* ip,int port,CFiberCtx *fiberctx);
   virtual int read(char* buf,int offset, int len,CFiberCtx 
*fiberctx);
   virtual int write(char* buf,int offset, int len,CFiberCtx 
*fiberctx); //ERROR : swap this line with below, everything will 
be ok
   virtual int readSome(char* buf,int offset, int len,CFiberCtx 
*fiberctx);
}

After swapping the last two lines, everything goes well.

The tutorial of d dont mention this.

Thanks for all replies.


More information about the Digitalmars-d-learn mailing list