Re: Binding to C - Arrays and Access Violation

2016-02-03 Thread Mike Parker via Digitalmars-d-learn

On Wednesday, 3 February 2016 at 04:19:37 UTC, jmh530 wrote:



A few extra questions: 1) In other parts of the code I'm using 
extern(System), but that doesn't work for these. Why is 
extern(C) used for function pointers?,


extern(C) is only used with function pointers when it's needed. 
It depends entirely on how the C library was compiled.  By 
default, most compilers compile with the cdecl calling 
convention, which is what extern(C) specifies in D code. Windows 
system libraries are usually compiled to use the stdcall calling 
convention. The D equivalent is extern(Windows). extern(System) 
translates to extern(Windows) on Windows and extern(C) elsewhere. 
Function pointers passed to C code need to have the same calling 
convention as that of the library to which they are passed.


2) You use const(double)*, in other parts of the code I had 
converted the C code from const char* to const(char*). Does it 
matter where the pointer * falls?


Technically, const(char)* is a mutable pointer to const data and 
const(char*) is an immutable pointer to const data.


Binding to C - Arrays and Access Violation

2016-02-02 Thread jmh530 via Digitalmars-d-learn
I'm working on generating a binding to a C library. I've got the 
.h file converted and can call some parts of the library with no 
errors. However, I have reached a stumbling block in a critical 
part.


The library requires passing function pointers to various 
functions in the library. When I try to run these functions, I 
get an Access Violation error. I enabled additional DMD warnings, 
which helped pinpoint the issue.


My D code calls a C function. One of the parameters to the C 
function is a function pointer to a D function. This D function 
(below) is one that I copied  from the C library's tutorial. I 
only slightly changed the signature. This function is eventually 
called in other functions in the C library.


double myfunc(uint n, const double* x, double* grad, void* 
my_func_data)

{
if (grad)
{
grad[0] = 0.0;
grad[1] = 0.5 / sqrt(x[1]);
}
return sqrt(x[1]);
}

The line (though likely the next will too) that causes a problem 
is


grad[0] = 0.0;

Thus, as it is an Access Violation, I'm guessing the issue is 
with accessing elements of arrays in the D function from the C 
function. I don't know. When I try to call the D function in D, 
it works, but I have to refer to x and grad as x.ptr and grad.ptr.


I'm not sure how to go about fixing this...


Re: Binding to C - Arrays and Access Violation

2016-02-02 Thread biozic via Digitalmars-d-learn

On Tuesday, 2 February 2016 at 22:56:28 UTC, jmh530 wrote:
I'm working on generating a binding to a C library. I've got 
the .h file converted and can call some parts of the library 
with no errors. However, I have reached a stumbling block in a 
critical part.


The library requires passing function pointers to various 
functions in the library. When I try to run these functions, I 
get an Access Violation error. I enabled additional DMD 
warnings, which helped pinpoint the issue.


My D code calls a C function. One of the parameters to the C 
function is a function pointer to a D function. This D function 
(below) is one that I copied  from the C library's tutorial. I 
only slightly changed the signature. This function is 
eventually called in other functions in the C library.


double myfunc(uint n, const double* x, double* grad, void* 
my_func_data)

{
if (grad)
{
grad[0] = 0.0;
grad[1] = 0.5 / sqrt(x[1]);
}
return sqrt(x[1]);
}

The line (though likely the next will too) that causes a 
problem is


grad[0] = 0.0;

Thus, as it is an Access Violation, I'm guessing the issue is 
with accessing elements of arrays in the D function from the C 
function. I don't know. When I try to call the D function in D, 
it works, but I have to refer to x and grad as x.ptr and 
grad.ptr.


I'm not sure how to go about fixing this...


Is grad allocated in the D code? If so, it could have been 
collected because the GC lost track of its use when passing to 
and from the C code. Or is grad owned by the C code? If so, 
either there is a bug in the library or it's misused, because its 
memory has been freed/has never been allocated/has gone out of 
scope.






Re: Binding to C - Arrays and Access Violation

2016-02-02 Thread Mike Parker via Digitalmars-d-learn

On Tuesday, 2 February 2016 at 22:56:28 UTC, jmh530 wrote:



My D code calls a C function. One of the parameters to the C 
function is a function pointer to a D function. This D function 
(below) is one that I copied  from the C library's tutorial. I 
only slightly changed the signature. This function is 
eventually called in other functions in the C library.


double myfunc(uint n, const double* x, double* grad, void* 
my_func_data)




Thus, as it is an Access Violation, I'm guessing the issue is 
with accessing elements of arrays in the D function from the C 
function. I don't know. When I try to call the D function in D, 
it works, but I have to refer to x and grad as x.ptr and 
grad.ptr.


I'm not sure how to go about fixing this...


The parameter to the C function should be declared as extern(C), 
and so should your function implementation.


extern(C) alias FuncPtr = double function(uint, const(double)*, 
double*, void*);

extern(C) void takeFuncPtr(FuncPtr);

extern(C) double myfunc(uint n, const(double)* x, double* grad, 
void* my_func_data) {

...
}

If you haven't done that, then this is quite possibly the root of 
your problem.





Re: Binding to C - Arrays and Access Violation

2016-02-02 Thread jmh530 via Digitalmars-d-learn

On Wednesday, 3 February 2016 at 00:28:24 UTC, biozic wrote:


Is grad allocated in the D code? If so, it could have been 
collected because the GC lost track of its use when passing to 
and from the C code. Or is grad owned by the C code? If so, 
either there is a bug in the library or it's misused, because 
its memory has been freed/has never been allocated/has gone out 
of scope.


grad is only created in the C code. I don't pass it myself.


Re: Binding to C - Arrays and Access Violation

2016-02-02 Thread jmh530 via Digitalmars-d-learn

On Wednesday, 3 February 2016 at 00:37:25 UTC, Mike Parker wrote:


The parameter to the C function should be declared as 
extern(C), and so should your function implementation.


extern(C) alias FuncPtr = double function(uint, const(double)*, 
double*, void*);

extern(C) void takeFuncPtr(FuncPtr);

extern(C) double myfunc(uint n, const(double)* x, double* grad, 
void* my_func_data) {

...
}

If you haven't done that, then this is quite possibly the root 
of your problem.


Success! Couldn't have done it without your help.

I had originally had the equivalent of FuncPtr as extern(C), but 
I had removed that because myfunc wouldn't compile. I hadn't 
thought of putting those modifications on myfunc. Just assumed 
that I did the function pointers wrong.


A few extra questions: 1) In other parts of the code I'm using 
extern(System), but that doesn't work for these. Why is extern(C) 
used for function pointers?, 2) You use const(double)*, in other 
parts of the code I had converted the C code from const char* to 
const(char*). Does it matter where the pointer * falls?