digitalmars.D.learn - D array to void* and back
- ref2401 (34/34) Aug 03 2015 Hello everyone,
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (20/22) Aug 03 2015 You are still in D, so int[] has a different meaning from a C array.
- ref2401 (2/4) Aug 03 2015 Yes I do. I hope there is a neat way to pass array's length too.
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (8/12) Aug 03 2015 Not possible in C. :( Common methods:
- Steven Schveighoffer (10/41) Aug 03 2015 In T[], length is stored first, then pointer. This is likely where you
Hello everyone,
I pass a D array as void* into a function.
When I'm trying to cast a void* parameter to a D array I get
'Access Violation' error.
However if I define ArrayLike struct which looks like D array
then casting will succeed.
What should I do? Should I stick to ArrayLike wrapper and just
live? :)
struct ArrayLike(T) {
this(T[] arr) {
ptr = arr.ptr;
length = arr.length;
}
T* ptr;
size_t length;
T[] asArray() {
return ptr[0 .. length];
}
}
void funcLibC_Array(void* data) {
int[] arr = *cast(int[]*)data;
writeln("funcLibC_Array: ", arr);
}
void funcLibC_ArrayLike(void* data) {
ArrayLike!int arrLike = *cast(ArrayLike!int*)data;
writeln("funcLibC_ArrayLike: ", arrLike.asArray());
}
void main(string[] args) {
int[] arr = [1, 2, 3];
auto arrLike = ArrayLike!int(arr);
funcLibC_ArrayLike(&arrLike);
funcLibC_Array(arr.ptr); // 'Access Violation error' is thrown
here.
}
Aug 03 2015
On 08/03/2015 02:23 PM, ref2401 wrote:
void funcLibC_Array(void* data) {
int[] arr = *cast(int[]*)data;
You are still in D, so int[] has a different meaning from a C array.
(D's arrays are array-like. ;) )
Since arr.ptr is the pointer to the first element, and since that is
exactly how C functions access array elements, do this:
import std.stdio;
void funcLibC_Array(void* data) {
int* arr = cast(int*)data;
writeln("funcLibC_Array: ", arr);
foreach (i; 0 .. 3) {
writeln(arr[i]);
}
}
void main(string[] args) {
int[] arr = [1, 2, 3];
funcLibC_Array(arr.ptr); // 'Access Violation error' is thrown here.
}
But you still need to communicate how many elements there are in the
array. (I used literal 3).
Ali
Aug 03 2015
On Monday, 3 August 2015 at 21:28:29 UTC, Ali Çehreli wrote:But you still need to communicate how many elements there are in the array. (I used literal 3).Yes I do. I hope there is a neat way to pass array's length too.
Aug 03 2015
On 08/03/2015 02:33 PM, ref2401 wrote:On Monday, 3 August 2015 at 21:28:29 UTC, Ali Çehreli wrote:Not possible in C. :( Common methods: * An array-like struct * A separate parameter for the number of elements * A sentinel value at the end of the array (e.g. '\0' for strings or NULL for arrays of pointers to objects, -1 where it is not valid as an element value, etc.) AliBut you still need to communicate how many elements there are in the array. (I used literal 3).Yes I do. I hope there is a neat way to pass array's length too.
Aug 03 2015
On 8/3/15 5:23 PM, ref2401 wrote:Hello everyone, I pass a D array as void* into a function. When I'm trying to cast a void* parameter to a D array I get 'Access Violation' error. However if I define ArrayLike struct which looks like D array then casting will succeed. What should I do? Should I stick to ArrayLike wrapper and just live? :) struct ArrayLike(T) { this(T[] arr) { ptr = arr.ptr; length = arr.length; } T* ptr; size_t length;In T[], length is stored first, then pointer. This is likely where you are getting hung up. You didn't post your C code, so I don't know exactly what you are expecting on the other side.T[] asArray() { return ptr[0 .. length]; } } void funcLibC_Array(void* data) { int[] arr = *cast(int[]*)data; writeln("funcLibC_Array: ", arr); } void funcLibC_ArrayLike(void* data) { ArrayLike!int arrLike = *cast(ArrayLike!int*)data; writeln("funcLibC_ArrayLike: ", arrLike.asArray()); } void main(string[] args) { int[] arr = [1, 2, 3]; auto arrLike = ArrayLike!int(arr); funcLibC_ArrayLike(&arrLike); funcLibC_Array(arr.ptr); // 'Access Violation error' is thrown here.This is wrong, arr.ptr is just the pointer to the DATA, not a pointer to an array struct (which contains pointer and length). You want to do funcLibC_Array(&arr); Posting your C code (at least the part that reestablishes the type from a void*) may give more clarity to what you are trying to do. -Steve
Aug 03 2015









=?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> 