digitalmars.D.learn - Call C function - Access violation
- TheDGuy (19/19) Jan 03 2016 I get an access violation with this code:
- anonymous (4/23) Jan 03 2016 Works for me after adding the needed imports and removing the wrong
- TheDGuy (9/13) Jan 03 2016 Okay, i think this C code should work (checked with cpp.sh):
- Gary Willoughby (15/17) Jan 03 2016 There are a few things you can do to improve your code to make it
- Gary Willoughby (3/6) Jan 03 2016 Forget this line, my mistake. Use `toStringz` and pass a pointer
- TheDGuy (13/20) Jan 03 2016 Hi and thanks for your answer. My code looks now like this:
- Gary Willoughby (13/35) Jan 03 2016 Use an import.
- TheDGuy (6/18) Jan 03 2016 Okay, thank you very much!
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; }
Jan 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.
Jan 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.
Jan 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?
Jan 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
Jan 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`: 2. When converting a char pointer to a D string use `std.conv.to!(string)`: 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`.
Jan 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.
Jan 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: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)*...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.
Jan 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: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");On Sunday, 3 January 2016 at 13:23:25 UTC, Gary Willoughby wrote: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)*...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.
Jan 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'?
Jan 03 2016
On 03.01.2016 21:32, TheDGuy wrote: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'?You're probably on Windows then? dmd doesn't recognize the .o extension on Windows, use .obj instead.
Jan 03 2016
On Sunday, 3 January 2016 at 21:20:35 UTC, anonymous wrote:On 03.01.2016 21:32, TheDGuy wrote:If i rename "test.o" to "test.obj" i get: 'Error: Module or Dictionary corrupt'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'?You're probably on Windows then? dmd doesn't recognize the .o extension on Windows, use .obj instead.
Jan 03 2016
On 03.01.2016 22:37, TheDGuy wrote:If i rename "test.o" to "test.obj" i get: 'Error: Module or Dictionary corrupt'My guess is, that means that dmd can't handle the object file format that gcc produces. Disclaimer: I don't know much about object formats, gcc, and Windows. I may be mistaken in what I write here. I think there are three object file formats that are relevant for us: * OMF: the format dmd uses by default on 32 bit Windows, * COFF: the format dmd uses on 64 bit Windows and in 32 bit mode with the -m32mscoff switch, * ELF: the format gcc uses by default (on Linux at least, maybe on Windows too). You should probably try to find out what gcc produces (by reading gcc documentation, I supppose). Then you need to get your D compiler and your C compiler to produce the same format. As mentioned, dmd has some switches that affect the used/expected object format: -m32 (OMF) -m64 (COFF) -m32mscoff (COFF). You can also try to get gcc to produce another format. I don't know how to do that. Or you can use another C compiler that produces a different format than gcc. I'd expect Digital Mars's (i.e. Walter's) dmc to be compatible with dmd and produce OMF files. Looks like there's a free download: http://www.digitalmars.com/download/freecompiler.html dmd's COFF mode is supposed to be compatible with Microsoft's Visual Studio. So that would be another option.
Jan 03 2016