Jump to page: 1 2
Thread overview
Call C function - Access violation
Jan 03, 2016
TheDGuy
Jan 03, 2016
anonymous
Jan 03, 2016
TheDGuy
Jan 03, 2016
anonymous
Jan 03, 2016
anonymous
Jan 03, 2016
Gary Willoughby
Jan 03, 2016
Gary Willoughby
Jan 03, 2016
TheDGuy
Jan 03, 2016
Gary Willoughby
Jan 03, 2016
TheDGuy
Jan 03, 2016
anonymous
Jan 03, 2016
TheDGuy
Jan 03, 2016
anonymous
January 03, 2016
I get an access violation with this code:

extern(C) char* write(char* text);

void main(string[] args){
	char[] text = "Hello World".dup; //.dup converts string to char[]
	text ~= '\0'; //append

	char* result = write(text.ptr); //you need .ptr
	const(char)[] s = cstr2dstr(result);
	writeln(s);
	readln(); //keep the window open
}

auto cstr2dstr(inout(char)* cstr)
{
	return cstr ? cstr[0 .. strlen(cstr)] : "";
}

--

#include std.stdio;

char* write(char* text){
	return text;
}

January 03, 2016
On 03.01.2016 13:30, TheDGuy wrote:
> I get an access violation with this code:
>
> extern(C) char* write(char* text);
>
> void main(string[] args){
>      char[] text = "Hello World".dup; //.dup converts string to char[]
>      text ~= '\0'; //append
>
>      char* result = write(text.ptr); //you need .ptr
>      const(char)[] s = cstr2dstr(result);
>      writeln(s);
>      readln(); //keep the window open
> }
>
> auto cstr2dstr(inout(char)* cstr)
> {
>      return cstr ? cstr[0 .. strlen(cstr)] : "";
> }
>
> --
>
> #include std.stdio;
>
> char* write(char* text){
>      return text;
> }
>

Works for me after adding the needed imports and removing the wrong include from the C file. Is this really the actual code you're running? Doesn't your C compiler reject that include? gcc does.
January 03, 2016
>
> Works for me after adding the needed imports and removing the wrong include from the C file. Is this really the actual code you're running? Doesn't your C compiler reject that include? gcc does.

Okay, i think this C code should work (checked with cpp.sh):

#import <stdio.h>
char* write(char* text){
	return text;
}
int main(void){
    return 0;
}


but i still get the access violation.


January 03, 2016
On 03.01.2016 14:01, TheDGuy wrote:
> Okay, i think this C code should work (checked with cpp.sh):
>
> #import <stdio.h>
> char* write(char* text){
>      return text;
> }
> int main(void){
>      return 0;
> }

Uh, no. 1) In C it's include, not import. 2) Now you have two main functions, that can't work.

You shouldn't get a segfault, though. You should get some compile/link error. Are you compiling the right files? Can the segfault be from something other than your program?
January 03, 2016
On 03.01.2016 14:12, anonymous wrote:
> You shouldn't get a segfault, though. You should get some compile/link
> error. Are you compiling the right files? Can the segfault be from
> something other than your program?

Oh, I see what's probably happening:

You compile the D program, but you don't compile and/or don't link the C object file. It segfaults then when trying to call the C function.

You need to compile the C file and pass it to dmd or the linker. For example:

gcc -c -otest.c.o test.c
dmd test.d test.c.o
./test
January 03, 2016
On Sunday, 3 January 2016 at 12:30:34 UTC, TheDGuy wrote:
> I get an access violation with this code:
>
> ...

There are a few things you can do to improve your code to make it easier to debug.

1. When converting a D string to a char pointer for use with C, use `std.string.toStringz`:

http://dlang.org/phobos/std_string.html#.toStringz

2. When converting a char pointer to a D string use `std.conv.to!(string)`:

http://dlang.org/phobos/std_conv.html#.to

3. Define C-style char pointers in D as `const(char)*`.
4. Don't use the variable name `text` as it conflicts with `std.conv.text`.


I think I've noticed one problem with the code above. You are using `text.ptr`. You shouldn't do that because you are passing a pointer not an array. Just use `text`.
January 03, 2016
On Sunday, 3 January 2016 at 13:23:25 UTC, Gary Willoughby wrote:
> I think I've noticed one problem with the code above. You are using `text.ptr`. You shouldn't do that because you are passing a pointer not an array. Just use `text`.

Forget this line, my mistake. Use `toStringz` and pass a pointer instead of an array.
January 03, 2016
On Sunday, 3 January 2016 at 13:25:04 UTC, Gary Willoughby wrote:
> On Sunday, 3 January 2016 at 13:23:25 UTC, Gary Willoughby wrote:
>> I think I've noticed one problem with the code above. You are using `text.ptr`. You shouldn't do that because you are passing a pointer not an array. Just use `text`.
>
> Forget this line, my mistake. Use `toStringz` and pass a pointer instead of an array.

Hi and thanks for your answer. My code looks now like this:

void main(string[] args){
	const(char)* val = "Hello World".std.string.toStringz;
	char* result = write(val);
	const(char)[] s = cstr2dstr(result);
	writeln(s);
	readln(); //keep the window open
}

But now i get the error: "function expected before(), not package std of type void" (refering to line 2).

And if i define the variable 'value' as 'const(char)*' i also have to rewrite my C-function to accept const(char)*...
January 03, 2016
On Sunday, 3 January 2016 at 19:24:46 UTC, TheDGuy wrote:
> On Sunday, 3 January 2016 at 13:25:04 UTC, Gary Willoughby wrote:
>> On Sunday, 3 January 2016 at 13:23:25 UTC, Gary Willoughby wrote:
>>> I think I've noticed one problem with the code above. You are using `text.ptr`. You shouldn't do that because you are passing a pointer not an array. Just use `text`.
>>
>> Forget this line, my mistake. Use `toStringz` and pass a pointer instead of an array.
>
> Hi and thanks for your answer. My code looks now like this:
>
> void main(string[] args){
> 	const(char)* val = "Hello World".std.string.toStringz;
> 	char* result = write(val);
> 	const(char)[] s = cstr2dstr(result);
> 	writeln(s);
> 	readln(); //keep the window open
> }
>
> But now i get the error: "function expected before(), not package std of type void" (refering to line 2).
>
> And if i define the variable 'value' as 'const(char)*' i also have to rewrite my C-function to accept const(char)*...

Use an import.

import std.string;
import std.conv;

void main(string[] args) {
    auto value  = toStringz("Hello World");
    auto result = write(value);
    auto s      = to!(string)(result);
    writeln(s);
}

Also all string literals in D are zero terminated so you could write the call like this:

auto result = write("Hello World");


January 03, 2016
>
> Use an import.
>
> import std.string;
> import std.conv;
>
> void main(string[] args) {
>     auto value  = toStringz("Hello World");
>     auto result = write(value);
>     auto s      = to!(string)(result);
>     writeln(s);
> }
>
> Also all string literals in D are zero terminated so you could write the call like this:
>
> auto result = write("Hello World");

Okay, thank you very much!

But now i get the access violation error again.

If i type:
gcc -c -otest.c.o

the 'test.c.o' file is generated but if i type:

dmd main.d test.c.o i get: 'Error: unrecognized file extension o'?
« First   ‹ Prev
1 2