Re: Memory management by interfacing C/C++
On Monday, 29 April 2019 at 14:38:54 UTC, 9il wrote: On Saturday, 27 April 2019 at 22:25:58 UTC, Ferhat Kurtulmuş wrote: [...] Hello Ferhat, You can use RCArray!T or Slice!(RCI!T) [1, 2] as common thread safe @nogc types for D and C++ code. See also integration C++ example [3] and C++ headers [4]. RCArray (fixed length) [1] http://mir-algorithm.libmir.org/mir_rc_array.html RCSlice (allows to get subslices) [2] http://mir-algorithm.libmir.org/mir_ndslice_allocation.html#rcslice C++ integration example [3] https://github.com/libmir/mir-algorithm/tree/master/cpp_example C++ headers [4] https://github.com/libmir/mir-algorithm/tree/master/include/mir An opencv d binding using ndslice substituting cv::Mat would be useful like opencv-python using numpy. However, I started opencvd about a month ago, and I am very new to d. For now, I am the only contributor with zero mir.ndslice experience. When I gain more experience with ndslice, I would try it as substitution for cv::Mat. Thank you for links 9il. I will take a look at them.
Re: Memory management by interfacing C/C++
On Saturday, 27 April 2019 at 22:25:58 UTC, Ferhat Kurtulmuş wrote: Hi, I am wrapping some C++ code for my personal project (opencvd), and I am creating so many array pointers at cpp side and containing them in structs. I want to learn if I am leaking memory like crazy, although I am not facing crashes so far. Is GC of D handling things for me? Here is an example: ``` //declaration in d struct IntVector { int* val; int length; } // in cpp typedef struct IntVector { int* val; int length; } IntVector; // cpp function returning a struct containing an array pointer allocated with "new" op. IntVector Subdiv2D_GetLeadingEdgeList(Subdiv2D sd){ std::vector iv; sd->getLeadingEdgeList(iv); int *cintv = new int[iv.size()]; // I don't call delete anywhere? for(size_t i=0; i < iv.size(); i++){ cintv[i] = iv[i]; } IntVector ret = {cintv, (int)iv.size()}; return ret; }; // call extern c function in d: extern (C) IntVector Subdiv2D_GetLeadingEdgeList(Subdiv2d sd); int[] getLeadingEdgeList(){ IntVector intv = Subdiv2D_GetLeadingEdgeList(this); int[] ret = intv.val[0..intv.length]; // just D magic. Still no delete anywhere! return ret; } ``` The question is now: what will happen to "int *cintv" which is allocated with new operator in cpp code? I have many code similar in the project, but I have not encounter any problem so far even in looped video processings. Is GC of D doing deallocation automagically? https://github.com/aferust/opencvd Hello Ferhat, You can use RCArray!T or Slice!(RCI!T) [1, 2] as common thread safe @nogc types for D and C++ code. See also integration C++ example [3] and C++ headers [4]. RCArray (fixed length) [1] http://mir-algorithm.libmir.org/mir_rc_array.html RCSlice (allows to get subslices) [2] http://mir-algorithm.libmir.org/mir_ndslice_allocation.html#rcslice C++ integration example [3] https://github.com/libmir/mir-algorithm/tree/master/cpp_example C++ headers [4] https://github.com/libmir/mir-algorithm/tree/master/include/mir
Re: Memory management by interfacing C/C++
On Monday, 29 April 2019 at 00:53:34 UTC, Paul Backus wrote: On Sunday, 28 April 2019 at 23:10:24 UTC, Ferhat Kurtulmuş wrote: You are right. I am rewriting the things using mallocs, and will use core.stdc.stdlib.free on d side. I am not sure if I can use core.stdc.stdlib.free to destroy arrays allocated with new op. core.stdc.stdlib.free is (as the name suggests) the standard C `free` function. As such, it can only be used to free memory allocated by the standard C functions `malloc`, `calloc`, and `realloc`. This is the same in D as it is in C and C++. Thank you. It is now like: /* c/cpp side */ extern (C) void deleteArr(void* arr); void deleteArr(void* arr){ delete[] arr; } struct IntVector Subdiv2D_GetLeadingEdgeList(Subdiv2D sd){ std::vector iv; sd->getLeadingEdgeList(iv); int *cintv = new int[iv.size()]; for(size_t i=0; i < iv.size(); i++){ cintv[i] = iv[i]; } IntVector ret = {cintv, (int)iv.size()}; return ret; }; /* c/cpp side */ ... int[] getLeadingEdgeList(){ // d function IntVector intv = Subdiv2D_GetLeadingEdgeList(this); int[] ret = intv.val[0..intv.length].dup; deleteArr(intv.val); return ret; } ...
Re: Memory management by interfacing C/C++
On Sunday, 28 April 2019 at 23:10:24 UTC, Ferhat Kurtulmuş wrote: You are right. I am rewriting the things using mallocs, and will use core.stdc.stdlib.free on d side. I am not sure if I can use core.stdc.stdlib.free to destroy arrays allocated with new op. core.stdc.stdlib.free is (as the name suggests) the standard C `free` function. As such, it can only be used to free memory allocated by the standard C functions `malloc`, `calloc`, and `realloc`. This is the same in D as it is in C and C++.
Re: Memory management by interfacing C/C++
On Sunday, 28 April 2019 at 03:54:17 UTC, Paul Backus wrote: On Saturday, 27 April 2019 at 22:25:58 UTC, Ferhat Kurtulmuş wrote: Hi, I am wrapping some C++ code for my personal project (opencvd), and I am creating so many array pointers at cpp side and containing them in structs. I want to learn if I am leaking memory like crazy, although I am not facing crashes so far. Is GC of D handling things for me? Here is an example: [...] The question is now: what will happen to "int *cintv" which is allocated with new operator in cpp code? I have many code similar in the project, but I have not encounter any problem so far even in looped video processings. Is GC of D doing deallocation automagically? https://github.com/aferust/opencvd D's GC only collects memory allocated with D's `new` operator. Memory allocated by C++'s `new` operator must be freed by C++'s `delete` operator. You are right. I am rewriting the things using mallocs, and will use core.stdc.stdlib.free on d side. I am not sure if I can use core.stdc.stdlib.free to destroy arrays allocated with new op.
Re: Memory management by interfacing C/C++
On Saturday, 27 April 2019 at 22:25:58 UTC, Ferhat Kurtulmuş wrote: Hi, I am wrapping some C++ code for my personal project (opencvd), and I am creating so many array pointers at cpp side and containing them in structs. I want to learn if I am leaking memory like crazy, although I am not facing crashes so far. Is GC of D handling things for me? Here is an example: [...] The question is now: what will happen to "int *cintv" which is allocated with new operator in cpp code? I have many code similar in the project, but I have not encounter any problem so far even in looped video processings. Is GC of D doing deallocation automagically? https://github.com/aferust/opencvd D's GC only collects memory allocated with D's `new` operator. Memory allocated by C++'s `new` operator must be freed by C++'s `delete` operator.
Memory management by interfacing C/C++
Hi, I am wrapping some C++ code for my personal project (opencvd), and I am creating so many array pointers at cpp side and containing them in structs. I want to learn if I am leaking memory like crazy, although I am not facing crashes so far. Is GC of D handling things for me? Here is an example: ``` //declaration in d struct IntVector { int* val; int length; } // in cpp typedef struct IntVector { int* val; int length; } IntVector; // cpp function returning a struct containing an array pointer allocated with "new" op. IntVector Subdiv2D_GetLeadingEdgeList(Subdiv2D sd){ std::vector iv; sd->getLeadingEdgeList(iv); int *cintv = new int[iv.size()]; // I don't call delete anywhere? for(size_t i=0; i < iv.size(); i++){ cintv[i] = iv[i]; } IntVector ret = {cintv, (int)iv.size()}; return ret; }; // call extern c function in d: extern (C) IntVector Subdiv2D_GetLeadingEdgeList(Subdiv2d sd); int[] getLeadingEdgeList(){ IntVector intv = Subdiv2D_GetLeadingEdgeList(this); int[] ret = intv.val[0..intv.length]; // just D magic. Still no delete anywhere! return ret; } ``` The question is now: what will happen to "int *cintv" which is allocated with new operator in cpp code? I have many code similar in the project, but I have not encounter any problem so far even in looped video processings. Is GC of D doing deallocation automagically? https://github.com/aferust/opencvd
Re: interfacing c++
22.11.2017 19:06, Markus пишет: another indicator (as documented) that GC destructor won't work // extern(C++) classes don't have a classinfo pointer in their vtable so the GC can't finalize them https://github.com/dlang/druntime/blob/3d8d4a45c01832fb657c16a656b6e1566d77fb21/src/rt/lifetime.d#L90 annoying :( Markus I've made a guess that more c++ support were added in the last frontend version, well I was wrong
Re: interfacing c++
another indicator (as documented) that GC destructor won't work // extern(C++) classes don't have a classinfo pointer in their vtable so the GC can't finalize them https://github.com/dlang/druntime/blob/3d8d4a45c01832fb657c16a656b6e1566d77fb21/src/rt/lifetime.d#L90 annoying :( Markus
Re: interfacing c++
On Wednesday, 22 November 2017 at 08:43:54 UTC, drug wrote: 22.11.2017 02:12, Markus пишет: What about dtor - you allocate class using D GC but try to destroy it manually - namely this I guess gives you an error in rt_finalize2 because it tries to destroy object that has been destroyed. hmm... I'm not sure. I compiled dmd and it's druntime in debug and I'm stepping through it. Seems there has to be a "ClassInfo" filled with data. In my case it's filled with garbage. So the call ClassInfo.destructor fails, because destructor is an invalid pointer. The GC.collect works, but doesn't call the destructor. https://github.com/dlang/druntime/blob/3d8d4a45c01832fb657c16a656b6e1566d77fb21/src/rt/lifetime.d#L1391 I know constructors and destructors are not supported. And I get that point for move/copy... constructors. But I don't get it for simple construction and destruction. Markus
Re: interfacing c++
22.11.2017 02:12, Markus пишет: snip I could do the instancing/destruction by functions and write a custom d class that calls these methods in this()/~this(). This is what I used to do as special members like ctor/dtor did not supported in D before, but your example of using ctor is interesting. What about dtor - you allocate class using D GC but try to destroy it manually - namely this I guess gives you an error in rt_finalize2 because it tries to destroy object that has been destroyed.
Re: interfacing c++
On Wednesday, 22 November 2017 at 08:29:26 UTC, MGW wrote: Possibly it will be interesting https://pp.userapi.com/c639524/v639524332/60240/uH3jnxrchik.jpg
Re: interfacing c++
On Tuesday, 21 November 2017 at 23:12:33 UTC, Markus wrote: hi, im trying to interface a cpp class. I'd like to interface a bigger library and I'm trying to figure out the minimum effort. Possibly it will be interesting https://www.youtube.com/watch?v=HTgJaRRfLPk
interfacing c++
hi, im trying to interface a cpp class. I'd like to interface a bigger library and I'm trying to figure out the minimum effort. --- c++ part: #include class some_class { public: static some_class* __ctor(); some_class(); ~some_class(); void some_method(); }; some_class* some_class::__ctor() { auto thiz = new some_class(); std::cout << "hello from __ctor, thiz:" << thiz << std::endl; return thiz; } some_class::some_class() { std::cout << "some_class constructor, this:" << this << std::endl; } some_class::~some_class() { std::cout << "some_class destructor, this:" << this << std::endl; } void some_class::some_method() { std::cout << "some_class some_method, this:" << this << std::endl; } --- d part: extern (C++) { class some_class { final this(); final ~this(); final void some_method(); } } void main() { some_class someClass = new some_class(); // works, __ctor() gets called, and it calls the constructor. someClass.some_method; // works destroy(someClass); // crashes (SIGSEGV) inside lifetime.d rt_finalize2() } --- OS: ubuntu 17.10 compiler: DMD64 D Compiler v2.077.0 I could do the instancing/destruction by functions and write a custom d class that calls these methods in this()/~this(). But I was hoping not needing to write a class in D AND in cpp. and i was hoping to save another step/level of instancing. Any idea how to make the destructor of cpp compatible with "~this()"? Thx in advance Markus
Re: Interfacing C++ to D
On Sunday, 2 April 2017 at 16:03:51 UTC, FreeSlave wrote: Funny thing: If I replace interface with abstract class, it works as it should. Also I noticed that removing inheritance in library and in application makes unexpected results. When I try to output field `field` I get incorrect random value. It looks like that the field is got by wrong address. For clearance I created branch `removed-inheritance`.
Re: Interfacing C++ to D
On Sunday, 2 April 2017 at 16:03:51 UTC, FreeSlave wrote: On Sunday, 2 April 2017 at 16:02:06 UTC, FreeSlave wrote: On Sunday, 2 April 2017 at 09:58:19 UTC, ANtlord wrote: [...] Now I see. 'Using C++ Classes From D' crashes for me too. It also returns the wrong value from 'field' method. Should be 5, but it returns 0. Probably regression. Funny thing: If I replace interface with abstract class, it works as it should. Reported issue: https://issues.dlang.org/show_bug.cgi?id=17293
Re: Interfacing C++ to D
On Sunday, 2 April 2017 at 16:02:06 UTC, FreeSlave wrote: On Sunday, 2 April 2017 at 09:58:19 UTC, ANtlord wrote: On Saturday, 1 April 2017 at 16:39:28 UTC, FreeSlave wrote: This page has many examples. Which exactly do you try to run and how do you build it? Which compilers, OS? My bad. I've tested example under caption Using C++ Classes From D. I used several combinations of compilers, and no one works for me. OS: ArchLinux D compilers: DMD 2.073.2, LDC 1.1.0 C++ compiler: gcc 6.3.1, clang 3.9 Also I've created reposotory contains test project. Anyone can take a look on that for clearance. https://github.com/ANtlord/cpp_to_d_test Now I see. 'Using C++ Classes From D' crashes for me too. It also returns the wrong value from 'field' method. Should be 5, but it returns 0. Probably regression. Funny thing: If I replace interface with abstract class, it works as it should.
Re: Interfacing C++ to D
On Sunday, 2 April 2017 at 09:58:19 UTC, ANtlord wrote: On Saturday, 1 April 2017 at 16:39:28 UTC, FreeSlave wrote: This page has many examples. Which exactly do you try to run and how do you build it? Which compilers, OS? My bad. I've tested example under caption Using C++ Classes From D. I used several combinations of compilers, and no one works for me. OS: ArchLinux D compilers: DMD 2.073.2, LDC 1.1.0 C++ compiler: gcc 6.3.1, clang 3.9 Also I've created reposotory contains test project. Anyone can take a look on that for clearance. https://github.com/ANtlord/cpp_to_d_test Now I see. 'Using C++ Classes From D' crashes for me too. It also returns the wrong value from 'field' method. Should be 5, but it returns 0. Probably regression.
Re: Interfacing C++ to D
On Sunday, 2 April 2017 at 09:58:19 UTC, ANtlord wrote: On Saturday, 1 April 2017 at 16:39:28 UTC, FreeSlave wrote: This page has many examples. Which exactly do you try to run and how do you build it? Which compilers, OS? My bad. I've tested example under caption Using C++ Classes From D. I used several combinations of compilers, and no one works for me. OS: ArchLinux D compilers: DMD 2.073.2, LDC 1.1.0 C++ compiler: gcc 6.3.1, clang 3.9 Also I've created reposotory contains test project. Anyone can take a look on that for clearance. https://github.com/ANtlord/cpp_to_d_test I've tested also on Ubuntu 16.04 and DMD v2.073.1 with gcc 5.4.0
Re: Interfacing C++ to D
On Saturday, 1 April 2017 at 16:39:28 UTC, FreeSlave wrote: This page has many examples. Which exactly do you try to run and how do you build it? Which compilers, OS? My bad. I've tested example under caption Using C++ Classes From D. I used several combinations of compilers, and no one works for me. OS: ArchLinux D compilers: DMD 2.073.2, LDC 1.1.0 C++ compiler: gcc 6.3.1, clang 3.9 Also I've created reposotory contains test project. Anyone can take a look on that for clearance. https://github.com/ANtlord/cpp_to_d_test
Re: Interfacing C++ to D
On Saturday, 1 April 2017 at 07:37:25 UTC, ANtlord wrote: Hello! Can somebody give a relevant example shows how to use C++ classes in D? I've used the exmaple from https://dlang.org/spec/cpp_interface.html but I get a segmentation fault as result of D application. My application shows "Program exited with code -11" Thanks. This page has many examples. Which exactly do you try to run and how do you build it? Which compilers, OS?
Interfacing C++ to D
Hello! Can somebody give a relevant example shows how to use C++ classes in D? I've used the exmaple from https://dlang.org/spec/cpp_interface.html but I get a segmentation fault as result of D application. My application shows "Program exited with code -11" Thanks.
Re: Interfacing C++ to D -- or better: C++ -- C --- D (DLL)
On Saturday, 29 March 2014 at 15:03:18 UTC, BeschBesch wrote: I want to use a set of functions that rely on a library which is not available for D (Harfbuzz). So I just wrote myself a set a functions that will do anything I need (Init, Free, Fonts, Text, etc). The DLL is working fine and dynamically linking should work (it does in C++ -- LoadLibrary). Unfortunately, i get Error 42 evertime i try to call a function. As i suspected that some things written by me could be responsible for this, I build a test application with three functions (Test, Test2,Test3), got myself the D-.lib for statical-linking (implib-Dmd) and tried that one out. The result: Error 42. What did I miss that can still cause linker errors? So far I did: DLL is written in C (C89 -- VC++ only can afford that one it seems). And yes I changed it to C from C++ in the compiler settings. DLL has an entry function AND a module-definition file (.def). A .lib-file is created alongside with the DLL (.def specified in porject settings). OF COURSE, I built a D-conform .lib by using implib with /s option (and without) /s option. Thank you, if you are still reading. CODE: // declared in Test.h void Test1(void); int Test2(int i); long Test3(int* ptr); // Example implementation in Test.c (include test.h void Test1(void) { printf(FUNCTION WAS CALLED\n); } / .def-File LIBRARY CtoDtestDll EXPORTS Test1 @1 Test2 @2 Test3 @3 /// SETTINGS (C++) Calling-convention: __cdecl (= std. ??) Compiling for: C (/TC) /// SETTINGS (LINKER) Modul-definition-file: CTestDll.def // D-Module for usage with .lib from .dll (implib! from bup) module CoreFuncs; // just a name pragma (lib,CtoDtestDll.lib); // statically linking (could user settings too) extern (C) /// needed so the compiler can link the functions { void Test(); } have you looked at exported symbols in dll? it may be C++ from what you said(lib not designed for C++?), so you can try extern(C++) on D side instead extern(C). or add manually #ifdef __cplusplus and extern C on lib side(if its not that big of course).
Re: Interfacing C++ to D -- or better: C++ -- C --- D (DLL)
have you looked at exported symbols in dll? it may be C++ from what you said(lib not designed for C++?), so you can try extern(C++) on D side instead extern(C). or add manually #ifdef __cplusplus and extern C on lib side(if its not that big of course). First of all: I started with a C++-dll and tried to declare the functions with extern (C++) -- did not work. Then I switched the compiler to C. As VC++ still uses only C89 as standard you can imagine there is NOTHING C++-ish that could have survived. I also tested this DLL in a C++-application (static) and it worked like a charm. ALSO: As i suspected that some things written by me could be responsible for this, I build a test application with three functions (Test, Test2,Test3), got myself the D-.lib for statical-linking (implib-Dmd) and tried that one out. The result: Error 42. So, actually I am trying to get a DLL containing three single-line test functions to work. What I have already achieved is to load it dynamically, and it worked (Derelict.Util.Loader.SharedLibLoader Class). As I also use the Derelict-packages, I may intend to build a custom loader class as a work-around.
Re: Interfacing C++ to D -- or better: C++ -- C --- D (DLL)
On Sunday, 30 March 2014 at 11:16:16 UTC, BeschBesch wrote: have you looked at exported symbols in dll? it may be C++ from what you said(lib not designed for C++?), so you can try extern(C++) on D side instead extern(C). or add manually #ifdef __cplusplus and extern C on lib side(if its not that big of course). First of all: I started with a C++-dll and tried to declare the functions with extern (C++) -- did not work. Then I switched the compiler to C. As VC++ still uses only C89 as standard you can imagine there is NOTHING C++-ish that could have survived. I also tested this DLL in a C++-application (static) and it worked like a charm. ALSO: As i suspected that some things written by me could be responsible for this, I build a test application with three functions (Test, Test2,Test3), got myself the D-.lib for statical-linking (implib-Dmd) and tried that one out. The result: Error 42. So, actually I am trying to get a DLL containing three single-line test functions to work. What I have already achieved is to load it dynamically, and it worked (Derelict.Util.Loader.SharedLibLoader Class). As I also use the Derelict-packages, I may intend to build a custom loader class as a work-around. it is not clear for me what are you trying to achieve and where/what is error 42. do you want implicit loading? if so, have you tried converting lib using coffimpblib tool from ftp.digitalmars.com? keep in mind that you don't have to convert libs when building in 64 bit mode.
Re: Interfacing C++ to D -- or better: C++ -- C --- D (DLL)
extern (C) /// needed so the compiler can link the functions { void Test(); } The function of course is called Test1 not Test.
Interfacing C++ to D -- or better: C++ -- C --- D (DLL)
I want to use a set of functions that rely on a library which is not available for D (Harfbuzz). So I just wrote myself a set a functions that will do anything I need (Init, Free, Fonts, Text, etc). The DLL is working fine and dynamically linking should work (it does in C++ -- LoadLibrary). Unfortunately, i get Error 42 evertime i try to call a function. As i suspected that some things written by me could be responsible for this, I build a test application with three functions (Test, Test2,Test3), got myself the D-.lib for statical-linking (implib-Dmd) and tried that one out. The result: Error 42. What did I miss that can still cause linker errors? So far I did: DLL is written in C (C89 -- VC++ only can afford that one it seems). And yes I changed it to C from C++ in the compiler settings. DLL has an entry function AND a module-definition file (.def). A .lib-file is created alongside with the DLL (.def specified in porject settings). OF COURSE, I built a D-conform .lib by using implib with /s option (and without) /s option. Thank you, if you are still reading. CODE: // declared in Test.h void Test1(void); int Test2(int i); long Test3(int* ptr); // Example implementation in Test.c (include test.h void Test1(void) { printf(FUNCTION WAS CALLED\n); } / .def-File LIBRARY CtoDtestDll EXPORTS Test1 @1 Test2 @2 Test3 @3 /// SETTINGS (C++) Calling-convention: __cdecl (= std. ??) Compiling for: C (/TC) /// SETTINGS (LINKER) Modul-definition-file: CTestDll.def // D-Module for usage with .lib from .dll (implib! from bup) module CoreFuncs; // just a name pragma (lib,CtoDtestDll.lib); // statically linking (could user settings too) extern (C) /// needed so the compiler can link the functions { void Test(); }
Re: Interfacing C programs: Pass D string to C function
On Friday, December 13, 2013 01:17:41 Jonathan M Davis wrote: or you could do something like auto cstr = str.dup.ptr; Wait. That was stupid of me. Don't do this. It'll give you a char*, but it won't be null-terminated. If you need char*, then use toUTFz!(char*) - though from what Mike's saying, it sounds like the problem was really your function prototype, which was supposed to take const char* rather than char*. - Jonathan M Davis
Interfacing C programs: Pass D string to C function
Hello I trying to write simple wrapper around pcre and have problem passing strings to it. As i understood, the best way is std.string.toStringZ. So, my code look like: string pattern = ; pcre_compile2( toStringz(pattern), options, errcode, errmsg, erroffset, cast(char*)null); This gives me error: Error: function pcre_compile2 (char*, int, int*, char**, int*, char*) is not callable using argument types (immutable(char)*, int, int*, char**, int*, char*) Any ideas for better way to do this task ?
Re: Interfacing C programs: Pass D string to C function
On Friday, 13 December 2013 at 08:00:21 UTC, Dfr wrote: Hello I trying to write simple wrapper around pcre and have problem passing strings to it. As i understood, the best way is std.string.toStringZ. So, my code look like: string pattern = ; pcre_compile2( toStringz(pattern), options, errcode, errmsg, erroffset, cast(char*)null); This gives me error: Error: function pcre_compile2 (char*, int, int*, char**, int*, char*) is not callable using argument types (immutable(char)*, int, int*, char**, int*, char*) Any ideas for better way to do this task ? Try using cast(char*)pattern
Re: Interfacing C programs: Pass D string to C function
On Friday, December 13, 2013 09:00:20 Dfr wrote: Hello I trying to write simple wrapper around pcre and have problem passing strings to it. As i understood, the best way is std.string.toStringZ. So, my code look like: string pattern = ; pcre_compile2( toStringz(pattern), options, errcode, errmsg, erroffset, cast(char*)null); This gives me error: Error: function pcre_compile2 (char*, int, int*, char**, int*, char*) is not callable using argument types (immutable(char)*, int, int*, char**, int*, char*) Any ideas for better way to do this task ? The problem is that toStringz returns immutable(char)* (because string is immutable(string)[]), and your function is taking char*. It will work to pass the result of toStringz to a C function which takes const char* (since immutable will implicitly convert to const), but immutable doesn't implicitly convert to mutable, and casting immutable mutable is almost always a bad idea. The easiest solution would be to use std.utf.toUTFz. e.g. auto cstr = str.toUTFz!(char*)(); or you could do something like auto cstr = str.dup.ptr; In either case, what you're doing is allocating a new char[] which holds the same elements as the original string and getting its ptr property so that you have a char*. - Jonathan M Davis
Re: Interfacing C programs: Pass D string to C function
On 12/13/2013 5:00 PM, Dfr wrote: Hello I trying to write simple wrapper around pcre and have problem passing strings to it. As i understood, the best way is std.string.toStringZ. So, my code look like: string pattern = ; pcre_compile2( toStringz(pattern), options, errcode, errmsg, erroffset, cast(char*)null); This gives me error: Error: function pcre_compile2 (char*, int, int*, char**, int*, char*) is not callable using argument types (immutable(char)*, int, int*, char**, int*, char*) Any ideas for better way to do this task ? Declare the function to like so: pcre* pcre_compile2( const(char)*, int, int*, const(char)**, int*, const(ubyte)*); This matches the C declaration according to [1]. immutable args can be passed to const params without seeing your error. Also, note the last paramters. In C, it's declared to be const unsigned char* and the documentation suggest it's intended to be treated as a byte array rather than a string. In that case, const(ubyte)* is the appropriate choice. D declarations of C functions should generally match the C version as closely as possible, including use of const, but with intent taken into account as well (e.g. byte array vs string). [1] https://code.google.com/p/wiimc/source/browse/trunk/libs/pcre/doc/html/pcre_compile2.html?r=423
Problem with interfacing C code to D
Dear i do not understand why the first example works and the second segfault. Thanks EXAMPLE 1 --- // ldc2 -L=/usr/lib64/libXlib.so -L-lX11 -g -w xtest.d import std.string; import std.stdio; import std.conv; import std.c.stdlib : getenv; import std.exception : Exception; import X11.Xlib; void main( string[] args ){ Display* display = XOpenDisplay(getenv(DISPLAY)); if( display is null ) new Exception( Could not communicate with X server ); int counter; string pattern = *\0; char** fonts = XListFonts( display, pattern.dup.ptr, 10, counter ); for(int c = 0; c counter; c++) writeln( to!string( fonts[c] ) ); } EXAMPLE 2 --- // ldc2 -L=/usr/lib64/libXlib.so -L-lX11 -g -w xtest.d import std.string; import std.stdio; import std.conv; import std.c.stdlib : getenv; import std.exception : Exception; import X11.Xlib; void main( string[] args ){ Display display = *XOpenDisplay(getenv(DISPLAY)); if( display is null ) new Exception( Could not communicate with X server ); int counter; string pattern = *\0; char** fonts = XListFonts( display, pattern.dup.ptr, 10, counter ); for(int c = 0; c counter; c++) writeln( to!string( fonts[c] ) ); }
Re: Problem with interfacing C code to D
What's the definition of Display?
Re: Problem with interfacing C code to D
Le mardi 10 janvier 2012 à 01:26 +0100, Trass3r a écrit : What's the definition of Display? This one: _ struct _XDisplay{ XExtData* ext_data; /* hook for extension to hang data */ _XPrivate* private1; int fd; /* Network socket. */ int private2; int proto_major_version;/* major version of server's X protocol */ int proto_minor_version;/* minor version of servers X protocol */ char* vendor; /* vendor of the server hardware */ XID private3; XID private4; XID private5; int private6; XID function(_XDisplay*)resource_alloc; /* allocator function */ int char_order; /* screen char order, LSBFirst, MSBFirst */ int bitmap_unit;/* padding and data requirements */ int bitmap_pad; /* padding requirements on bitmaps */ int bitmap_bit_order; /* LeastSignificant or MostSignificant */ int nformats; /* number of pixmap formats in list */ ScreenFormat* pixmap_format;/* pixmap format list */ int private8; int release;/* release of the server */ _XPrivate* private9, private10; int qlen; /* Length of input event queue */ c_ulong last_request_read; /* seq number of last event read */ c_ulong request; /* sequence number of last request. */ XPointer private11; XPointer private12; XPointer private13; XPointer private14; uint max_request_size; /* maximum number 32 bit words in request*/ _XrmHashBucketRec* db; int function( _XDisplay* )private15; char* display_name; /* host:display string used on this connect*/ int default_screen; /* default screen for operations */ int nscreens; /* number of screens on this server*/ Screen* screens;/* pointer to list of screens */ c_ulong motion_buffer; /* size of motion buffer */ c_ulong private16; int min_keycode;/* minimum defined keycode */ int max_keycode;/* maximum defined keycode */ XPointer private17; XPointer private18; int private19; char* xdefaults;/* contents of defaults from server */ /* there is more to this structure, but it is private to Xlib */ } alias _XDisplay Display;
Re: Problem with interfacing C code to D
It's likely a module Gmail - Problem with interfacing C code to D - Mozilla Firefo; import std.algorithm; import std.array; import std.stdio; void main() { } On 1/10/12, bioinfornatics bioinfornat...@fedoraproject.org wrote: Le mardi 10 janvier 2012 à 01:26 +0100, Trass3r a écrit : What's the definition of Display? This one: _ struct _XDisplay{ XExtData* ext_data; /* hook for extension to hang data */ _XPrivate* private1; int fd; /* Network socket. */ int private2; int proto_major_version;/* major version of server's X protocol */ int proto_minor_version;/* minor version of servers X protocol */ char* vendor; /* vendor of the server hardware */ XID private3; XID private4; XID private5; int private6; XID function(_XDisplay*)resource_alloc; /* allocator function */ int char_order; /* screen char order, LSBFirst, MSBFirst */ int bitmap_unit;/* padding and data requirements */ int bitmap_pad; /* padding requirements on bitmaps */ int bitmap_bit_order; /* LeastSignificant or MostSignificant */ int nformats; /* number of pixmap formats in list */ ScreenFormat* pixmap_format;/* pixmap format list */ int private8; int release;/* release of the server */ _XPrivate* private9, private10; int qlen; /* Length of input event queue */ c_ulong last_request_read; /* seq number of last event read */ c_ulong request; /* sequence number of last request. */ XPointer private11; XPointer private12; XPointer private13; XPointer private14; uint max_request_size; /* maximum number 32 bit words in request*/ _XrmHashBucketRec* db; int function( _XDisplay* )private15; char* display_name; /* host:display string used on this connect*/ int default_screen; /* default screen for operations */ int nscreens; /* number of screens on this server*/ Screen* screens;/* pointer to list of screens */ c_ulong motion_buffer; /* size of motion buffer */ c_ulong private16; int min_keycode;/* minimum defined keycode */ int max_keycode;/* maximum defined keycode */ XPointer private17; XPointer private18; int private19; char* xdefaults;/* contents of defaults from server */ /* there is more to this structure, but it is private to Xlib */ } alias _XDisplay Display;
Re: Problem with interfacing C code to D
Jesus christ, sorry about that my keyboard script went crazy and posted that. What I was going to say is it's likely a mismatch of the struct sizes. In the second example you are dereferencing the pointer on the D size, which does a field-by-field copy of the pointed-to struct. But D will only read the exact amount of bytes that is defined by the structure. So if you end up reading e.g 176 bytes, but the C structure is actually more than that, then the C-side (X11) will end up reading into D memory past the 176th byte, and will segfault. If you can, try seeing if you can get the size of the Display structure in C code (e.g. use printf(%d, sizeof(Display))), and then compare that to D with writeln(Display.sizeof). They must have the same size.
Re: Problem with interfacing C code to D
On 01/10/12 01:02, bioinfornatics wrote: Dear i do not understand why the first example works and the second segfault. Thanks EXAMPLE 1 --- Display* display = XOpenDisplay(getenv(DISPLAY)); char** fonts = XListFonts( display, pattern.dup.ptr, 10, counter EXAMPLE 2 --- Display display = *XOpenDisplay(getenv(DISPLAY)); char** fonts = XListFonts( display, pattern.dup.ptr, 10, counter Do you expect the xlib functions to work with copies of private structures? artur
Re: Problem with interfacing C code to D
Scratch that, in X11 apparently the Display structure is an incomplete type (so sizeof won't work). This means you most probably *have* to use pass it around as an opaque pointer. It's kind of odd because you can still access some of its fields (so it's not totally opaque), but you can't do copies. So just use pointers and you'll be safe. Hell I've never really done any C programming except what's in KR, but this seems like a logical conclusion to me..