Jump to page: 1 2
Thread overview
Linking with FFmpeg
Jan 06, 2013
MrOrdinaire
Jan 06, 2013
bearophile
Jan 06, 2013
MrOrdinaire
Jan 06, 2013
bearophile
Jan 06, 2013
Johannes Pfau
Jan 06, 2013
bearophile
Jan 06, 2013
bearophile
Jan 06, 2013
MrOrdinaire
Jan 06, 2013
Johannes Pfau
Jan 06, 2013
MrOrdinaire
Jan 06, 2013
H. S. Teoh
Jan 06, 2013
Ali Çehreli
Jan 06, 2013
Johannes Pfau
Jan 07, 2013
MrOrdinaire
Jan 07, 2013
Johannes Pfau
January 06, 2013
Hi,

I am working on D bindings for FFmpeg. I am trying to port the official examples of FFmpeg to D so that the bindings can be tested.

My question is how this function declaration is written in D.
int av_image_alloc(uint8_t *pointers[4], int linesizes[4],
                   int w, int h, enum AVPixelFormat pix_fmt, int align);

My best guess is the following.
extern(C) int av_image_alloc(ref uint8_t[4] *pointers, ref int[4] linesizes,
                             int w, int h, AVPixelFormat pix_fmt, int align_);

However, calling this would give nonsense value for the array passed as linesizes. I don't know how to look at the variable passed as pointers yet.

The whole source of the port is at https://gist.github.com/4466289, there you can also find the link to the original source.

Thanks,
Minh
January 06, 2013
MrOrdinaire:

> My question is how this function declaration is written in D.
> int av_image_alloc(uint8_t *pointers[4], int linesizes[4],
>                    int w, int h, enum AVPixelFormat pix_fmt, int align);
>
> My best guess is the following.
> extern(C) int av_image_alloc(ref uint8_t[4] *pointers, ref int[4] linesizes,
>                              int w, int h, AVPixelFormat pix_fmt, int align_);

D ints are 32 bit long, while the length of C ints varies across different architectures. So you can't use int in your D signature. sizediff_t is better, but I remember there is a more specific type for this purpose, something like cint_t, I don't remember.

In D the pointer symbol "*" is better (more meaningful) written justified on the right.

If you use a D ref, you can't put a null there.

Others will give you a better answer.

Bye,
bearophile
January 06, 2013
On Sunday, 6 January 2013 at 10:21:56 UTC, bearophile wrote:
> MrOrdinaire:
>
>> My question is how this function declaration is written in D.
>> int av_image_alloc(uint8_t *pointers[4], int linesizes[4],
>>                   int w, int h, enum AVPixelFormat pix_fmt, int align);
>>
>> My best guess is the following.
>> extern(C) int av_image_alloc(ref uint8_t[4] *pointers, ref int[4] linesizes,
>>                             int w, int h, AVPixelFormat pix_fmt, int align_);
>
> D ints are 32 bit long, while the length of C ints varies across different architectures. So you can't use int in your D signature. sizediff_t is better, but I remember there is a more specific type for this purpose, something like cint_t, I don't remember.
>
> In D the pointer symbol "*" is better (more meaningful) written justified on the right.
>
> If you use a D ref, you can't put a null there.
>
> Others will give you a better answer.
>
> Bye,
> bearophile

Thank you for your reply.

I cannot find "cint_t" nor "cint" in the d standard modules (mine are at /usr/include/d/).

For the symbol "*", do you mean I should write something like this?
uint8_t[4]* ptrs

- Minh
January 06, 2013
MrOrdinaire:

> I cannot find "cint_t" nor "cint" in the d standard modules (mine are at /usr/include/d/).

I don't remember the correct name.


> For the symbol "*", do you mean I should write something like this?
> uint8_t[4]* ptrs

Right. It's a D coding style convention that has a practical base. In C this means a is a pointer and b is an integer, while in D it means both are pointers:

int *a, b;

In C this means a is an int and b is a pointer, while in D it's thankfully an error (Error: multiple declarations must have the same type, not int and int*):

int a, *b;

Bye,
bearophile
January 06, 2013
MrOrdinaire:

> For the symbol "*", do you mean I should write something like this?
> uint8_t[4]* ptrs

In D "ubyte" is probably enough, instead of "uint8_t".

Bye,
bearophile
January 06, 2013
Am Sun, 06 Jan 2013 12:51:33 +0100
schrieb "bearophile" <bearophileHUGS@lycos.com>:

> MrOrdinaire:
> 
> > I cannot find "cint_t" nor "cint" in the d standard modules (mine are at /usr/include/d/).
> 
> I don't remember the correct name.
> 

Are you sure about c_int? I never heard of that before, I only know c_long and c_ulong (in core.stdc.config).

http://dlang.org/interfaceToC.html

also says C int is the same as D int.

January 06, 2013
Am Sun, 06 Jan 2013 10:48:25 +0100
schrieb "MrOrdinaire" <mrordinaire@gmail.com>:

> Hi,
> 
> I am working on D bindings for FFmpeg. I am trying to port the official examples of FFmpeg to D so that the bindings can be tested.
> 
> My question is how this function declaration is written in D.
> int av_image_alloc(uint8_t *pointers[4], int linesizes[4],
>                     int w, int h, enum AVPixelFormat pix_fmt, int
> align);
> 

My C is pretty bad, is uint8_t *pointers[4] a static array with 4 elements of uint8_t* or is it a pointer to a static array with 4 uint8_t elements?

I guess it's the former, so in D it's (uint8_t*)[4] or better
(ubyte*)[4]. In D static arrays are passed by value, in C by reference,
so you have to do this:

extern(C) int av_image_alloc(ref (ubyte*)[4] pointers, ref int[4]
linesizes, int w, int h, AVPixelFormat pix_fmt, int align_);


Some more information is here: http://dlang.org/interfaceToC.html
January 06, 2013
On Sun, Jan 06, 2013 at 10:48:25AM +0100, MrOrdinaire wrote:
> Hi,
> 
> I am working on D bindings for FFmpeg. I am trying to port the official examples of FFmpeg to D so that the bindings can be tested.
> 
> My question is how this function declaration is written in D.
> int av_image_alloc(uint8_t *pointers[4], int linesizes[4],
>                    int w, int h, enum AVPixelFormat pix_fmt, int
> align);
> 
> My best guess is the following.
> extern(C) int av_image_alloc(ref uint8_t[4] *pointers, ref int[4]
> linesizes,
>                              int w, int h, AVPixelFormat pix_fmt,
> int align_);

The first parameter should be: uint8_t* pointers, and you need to call it like this:

	uint8_t[4] pointers;
	int[4] linesizes;
	auto ret = av_image_alloc(pointers.ptr, linesizes.ptr, ...);

To make it D-friendly, you might want to consider using a wrapper function that takes ref uint8_t[4] and ref int[4] instead.


> However, calling this would give nonsense value for the array passed as linesizes. I don't know how to look at the variable passed as pointers yet.
[...]

Just write *ptr to dereference a pointer. You can also take advantage of D's auto-dereferencing:

	struct S {
		int val = 123;
	}
	S s;
	S* ptr = &s;
	writeln(s.val);		// prints 123
	writeln(ptr.val);	// also prints 123 (ptr is automatically
				// dereferenced)

Finally, please note that in D, the * in pointer types associate with the _type_ rather than the variable name (as in C/C++), so you should always write "int* x,y" instead of "int *x, *y". Similarly, an array of pointers is written as "int*[] arr", whereas writing "int[]* arr" is actually declaring a pointer to an array. (In D, pointers and arrays are not the same thing.)


T

-- 
I don't trust computers, I've spent too long programming to think that they can get anything right. -- James Miller
January 06, 2013
On Sunday, 6 January 2013 at 11:54:34 UTC, bearophile wrote:
> MrOrdinaire:
>
>> For the symbol "*", do you mean I should write something like this?
>> uint8_t[4]* ptrs
>
> In D "ubyte" is probably enough, instead of "uint8_t".
>
> Bye,
> bearophile

Thanks for noting that. I know that in std.stdint, uint8_t is an alias for ubyte. However, I want to keep to the original source so that people can do a diff more easily.

- Minh
January 06, 2013
On Sunday, 6 January 2013 at 12:46:05 UTC, Johannes Pfau wrote:
> Am Sun, 06 Jan 2013 10:48:25 +0100
> schrieb "MrOrdinaire" <mrordinaire@gmail.com>:
>
>> Hi,
>> 
>> I am working on D bindings for FFmpeg. I am trying to port the official examples of FFmpeg to D so that the bindings can be tested.
>> 
>> My question is how this function declaration is written in D.
>> int av_image_alloc(uint8_t *pointers[4], int linesizes[4],
>>                     int w, int h, enum AVPixelFormat pix_fmt, int align);
>> 
>
> My C is pretty bad, is uint8_t *pointers[4] a static array with 4
> elements of uint8_t* or is it a pointer to a static array with 4
> uint8_t elements?
>
> I guess it's the former, so in D it's (uint8_t*)[4] or better
> (ubyte*)[4]. In D static arrays are passed by value, in C by reference,
> so you have to do this:
>
> extern(C) int av_image_alloc(ref (ubyte*)[4] pointers, ref int[4]
> linesizes, int w, int h, AVPixelFormat pix_fmt, int align_);
>
>
> Some more information is here:
> http://dlang.org/interfaceToC.html

According to this (http://c-faq.com/decl/spiral.anderson.html), I think pointers is an array of 4 pointers to uint8_t.

So in D, you read declarations from right to left?

- Minh
« First   ‹ Prev
1 2