Thread overview | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
|
August 08, 2012 two-dimensional C array and its analog in D | ||||
---|---|---|---|---|
| ||||
Hello, there is the following C function: void foo(const void** data); in C I can do: int data[N][M]; data[0][0] = ..; data[0][1] = ..; data[1][0] = ..; data[1][1] = ..; foo(data); // for C code it works and in D code it doesn't (compile, but do nothing) I've "solved" the problem like this: int real_data[N*M]; real_data[0] = ..; real_data[1] = ..; real_data[2] = ..; real_data[3] = ..; int* data[N]; foreach(i; 0..N) data[i] = &real_data[i*M]; T.i. I form an array of pointers by myself without compiler so it doesn't seem to be good enough for some overcode and it looks dirty a little bit. Is there more suitable variant? P.S. in few words I'd like to construct some D data structure that is binary compatible with two-dimensional C array (and do it in simple way, of course). |
August 08, 2012 Re: two-dimensional C array and its analog in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Alexandr Druzhinin | On 08/07/2012 11:07 PM, Alexandr Druzhinin wrote: > Hello, > there is the following C function: > > void foo(const void** data); > > in C I can do: > > int data[N][M]; > > data[0][0] = ..; > data[0][1] = ..; > data[1][0] = ..; > data[1][1] = ..; > > foo(data); // for C code it works and in D code it doesn't (compile, but > do nothing) This seems to work: import std.stdio; void main() { enum M = 3; enum N = 4; int[M][N] data; data[0][0] = 42; writeln(data); } The output: [[42, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]] Ali |
August 08, 2012 Re: two-dimensional C array and its analog in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Alexandr Druzhinin | Alexandr Druzhinin:
> there is the following C function:
>
> void foo(const void** data);
>
> in C I can do:
>
> int data[N][M];
>
> data[0][0] = ..;
> data[0][1] = ..;
> data[1][0] = ..;
> data[1][1] = ..;
>
> foo(data); // for C code it works and in D code it doesn't (compile, but do nothing)
That C code doesn't look correct, because the given data contains
no pointers.
Why don't you show us a complete compilable runnable correct tiny
C program, that we have to translate to D?
Bye,
bearophile
|
August 08, 2012 Re: two-dimensional C array and its analog in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | > That C code doesn't look correct, because the given data contains no pointers.
But this C code compiles:
void foo(const void** data) {}
int data[2][3];
int main() {
foo(data);
return 0;
}
Bye,
bearophile
|
August 08, 2012 Re: two-dimensional C array and its analog in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | 08.08.2012 16:29, bearophile пишет:
>> That C code doesn't look correct, because the given data contains no
>> pointers.
>
> But this C code compiles:
>
>
> void foo(const void** data) {}
> int data[2][3];
> int main() {
> foo(data);
> return 0;
> }
>
> Bye,
> bearophile
As I know in C an array is equal to pointer, so array of array == array of pointers == pointer to pointer == pointer to array. Correct me if I'm wrong.
I'm trying to use OpenGL function glMultiDrawElements. It has signature:
void glMultiDrawElements(
enum mode,
sizei *count,
enum type,
void **indices,
sizei primcount
);
If I declare indices like
uint[][] indices;
then code compiles but doesn't work (but it works in C). If I do as I described in the first post - it works in D. And I'd like to understand the reason of it. I think the reason is difference tween C array and D array, but I'm not sure.
p.s. example of real code is too large to paste
|
August 08, 2012 Re: two-dimensional C array and its analog in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | 08.08.2012 12:13, Ali Çehreli пишет:
>
> This seems to work:
>
> import std.stdio;
>
> void main()
> {
> enum M = 3;
> enum N = 4;
>
> int[M][N] data;
> data[0][0] = 42;
> writeln(data);
> }
>
> The output:
>
> [[42, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]
>
> Ali
>
I mean that I call C function from D code. And C function takes void** pointer as its argument. In C this means array of array, but if I pass D two-dimensional array it doesn't work (but compiles).
|
August 08, 2012 Re: two-dimensional C array and its analog in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Alexandr Druzhinin |
> I mean that I call C function from D code. And C function takes void** pointer as its argument. In C this means array of array, but if I pass D two-dimensional array it doesn't work (but compiles).
I'm pretty sure that the issue is D's internal implementation of 2-dimensional arrays. From what I remember, if the arrays are defined as fixed-size, D creates just a single block of array data rather than creating pointers to pointers. OpenGL is expecting an array of pointers to 1-dimensional arrays, but D is giving it the pointer to the actual indices.
|
August 08, 2012 Re: two-dimensional C array and its analog in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Alexandr Druzhinin | On 08/08/2012 07:12 AM, Alexandr Druzhinin wrote: > 08.08.2012 16:29, bearophile пишет: >>> That C code doesn't look correct, because the given data contains no >>> pointers. >> >> But this C code compiles: >> >> >> void foo(const void** data) {} >> int data[2][3]; >> int main() { >> foo(data); >> return 0; >> } gcc does not accept that code: deneme.c:18920: error: passing argument 1 of ‘foo’ from incompatible pointer type deneme.c:18914: note: expected ‘const void **’ but argument is of type ‘int (*)[3]’ > As I know in C an array is equal to pointer, In C and C++, an Array is automatically converted to a pointer to its first element. > so array of array == array > of pointers == pointer to pointer == pointer to array. Correct me if I'm > wrong. > > I'm trying to use OpenGL function glMultiDrawElements. It has signature: > void glMultiDrawElements( > enum mode, > sizei *count, > enum type, > void **indices, > sizei primcount > ); I looked at its online documentation: count is also an array that tells the lengths of individual rows of indices, right? So in reality the data is a dynamic ragged array? (I've never used that function before.) > If I declare indices like > uint[][] indices; That's a slice of uint slices. Completely different memory layout than static arrays. In any case, I am pretty sure that what you need is the .ptr property of D arrays. You will have to make the 'indices' parameter dynamically by calling .ptr on the slices. > then code compiles but doesn't work (but it works in C). If I do as I > described in the first post - it works in D. And I'd like to understand > the reason of it. I think the reason is difference tween C array and D > array, but I'm not sure. > > p.s. example of real code is too large to paste I've started writing the following but I don't know how you are calling the function. Can you get this to do what you expect in C: // WARNING: THIS C CODE DOES NOT COMPILE. #include <stdio.h> typedef size_t sizei; void glMultiDrawElements( /* enum mode,*/ sizei *count, /* enum type,*/ void **indices, sizei primcount) { for (size_t i = 0; i != primcount; ++i) { for (size_t j = 0; j != count[i]; ++j) { printf(" %d", indices[i][j]); } printf("\n"); } } int main() { /* Normally, the count array would be generated dynamically. */ int counts[4] = { 3, 3, 3, 3 }; int data[4][3]; data[0][0] = 42; data[2][2] = 43; glMultiDrawElements(counts, data, 4); } Ali -- D Programming Language Tutorial: http://ddili.org/ders/d.en/index.html |
August 08, 2012 Re: two-dimensional C array and its analog in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | 08.08.2012 22:21, Ali Çehreli пишет: > > I looked at its online documentation: count is also an array that tells > the lengths of individual rows of indices, right? So in reality the data > is a dynamic ragged array? (I've never used that function before.) Yes, it is. > > > If I declare indices like > > uint[][] indices; > > That's a slice of uint slices. Completely different memory layout than > static arrays. Ok. I'll read about slices once again > In any case, I am pretty sure that what you need is the .ptr property of > D arrays. You will have to make the 'indices' parameter dynamically by > calling .ptr on the slices. .ptr works fine. if I do, for example so: uint[] firstSubArray; uint[] secondSubArray; uint*[] indicies; indicies[0] = firstSubArray.ptr; indicies[1] = secondSubArray.ptr; that is I manually form array of pointers. But I don't like it. > > I've started writing the following but I don't know how you are calling > the function. Can you get this to do what you expect in C: > > // WARNING: THIS C CODE DOES NOT COMPILE. > #include <stdio.h> > > typedef size_t sizei; > > void glMultiDrawElements( > /* enum mode,*/ > sizei *count, > /* enum type,*/ > void **indices, > sizei primcount) > { > for (size_t i = 0; i != primcount; ++i) { > for (size_t j = 0; j != count[i]; ++j) { > printf(" %d", indices[i][j]); > } > printf("\n"); > } > } > > int main() > { > /* Normally, the count array would be generated dynamically. */ > int counts[4] = { 3, 3, 3, 3 }; > > int data[4][3]; > data[0][0] = 42; > data[2][2] = 43; > > glMultiDrawElements(counts, data, 4); > } yes, it looks like what I mean, but I'm sleepy now :) |
Copyright © 1999-2021 by the D Language Foundation