D - C(/C++) interoperability
- Matthew Wilson (7/7) Mar 20 2003 I know that one can declare something extern (C) to use a function writt...
- Walter (8/14) Mar 20 2003 All you need to do is return a struct that looks like this:
- Matthew Wilson (4/20) Mar 21 2003 allocated from where?
- Walter (6/31) Mar 21 2003 It's returned in the register pair EDX:EAX, so it doesn't matter where i...
- Russ Lewis (10/26) Mar 21 2003 Walter, I know that yo ucan do this, but it is a very bad idea! This st...
- Ilya Minkov (5/9) Mar 21 2003 It's the same with "%.*s" printf format - it relies upon this struct
- Matthew Wilson (45/45) Mar 21 2003 I'm not sure I'm expressing myself correctly here.
- Ilya Minkov (14/18) Mar 22 2003 I haven't read it, but ... isn't it also doable in D? If not, then why?
- Matthew Wilson (17/35) Mar 22 2003 Thanks. Will check it out there. :)
- Walter (16/24) Mar 24 2003 become
- Matthew Wilson (74/98) Mar 24 2003 As I said in the earlier post, I want to do this
I know that one can declare something extern (C) to use a function written in C from within D source. I want to create a C function that can return (D-type) char[]. Is this possible? I presume it'll require some C include files for the D infrastructure ... All help gratefully received. Matthew
Mar 20 2003
"Matthew Wilson" <dmd synesis.com.au> wrote in message news:b5e2ar$2l47$1 digitaldaemon.com...I know that one can declare something extern (C) to use a function written in C from within D source. I want to create a C function that can return (D-type) char[]. Is this possible? I presume it'll require some C include files for the D infrastructure ... All help gratefully received.All you need to do is return a struct that looks like this: struct Array { int length; void *data; };
Mar 20 2003
allocated from where? "Walter" <walter digitalmars.com> wrote in message news:b5eb13$2tuh$1 digitaldaemon.com..."Matthew Wilson" <dmd synesis.com.au> wrote in message news:b5e2ar$2l47$1 digitaldaemon.com...writtenI know that one can declare something extern (C) to use a functionin C from within D source. I want to create a C function that can return (D-type) char[]. Is this possible? I presume it'll require some C include files for the D infrastructure ... All help gratefully received.All you need to do is return a struct that looks like this: struct Array { int length; void *data; };
Mar 21 2003
It's returned in the register pair EDX:EAX, so it doesn't matter where it is allocated. "Matthew Wilson" <dmd synesis.com.au> wrote in message news:b5ehu2$3kd$1 digitaldaemon.com...allocated from where? "Walter" <walter digitalmars.com> wrote in message news:b5eb13$2tuh$1 digitaldaemon.com...return"Matthew Wilson" <dmd synesis.com.au> wrote in message news:b5e2ar$2l47$1 digitaldaemon.com...writtenI know that one can declare something extern (C) to use a functionin C from within D source. I want to create a C function that canD(D-type) char[]. Is this possible? I presume it'll require some C include files for theinfrastructure ... All help gratefully received.All you need to do is return a struct that looks like this: struct Array { int length; void *data; };
Mar 21 2003
Walter wrote:"Matthew Wilson" <dmd synesis.com.au> wrote in message news:b5e2ar$2l47$1 digitaldaemon.com...Walter, I know that yo ucan do this, but it is a very bad idea! This struct is not defined in the spec, so it totally depends on the implementation of the compiler. We need to define a standard way to do this, even if the standard is simply this. -- The Villagers are Online! villagersonline.com .[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ] .[ (a version.of(English).(precise.more)) is(possible) ] ?[ you want.to(help(develop(it))) ]I know that one can declare something extern (C) to use a function written in C from within D source. I want to create a C function that can return (D-type) char[]. Is this possible? I presume it'll require some C include files for the D infrastructure ... All help gratefully received.All you need to do is return a struct that looks like this: struct Array { int length; void *data; };
Mar 21 2003
Russ Lewis wrote:Walter, I know that yo ucan do this, but it is a very bad idea! This struct is not defined in the spec, so it totally depends on the implementation of the compiler. We need to define a standard way to do this, even if the standard is simply this.It's the same with "%.*s" printf format - it relies upon this struct just as well. So it can be considered as a part of specification. It is even mentioned under "memory layout" in the spec. -i.
Mar 21 2003
I'm not sure I'm expressing myself correctly here. I want to write a set of functions in C++, that are importable as D, and which create and operate on D types. Specifically, I want to create the following D functions: char[] integer_to_string(bit value); char[] integer_to_string(byte value); char[] integer_to_string(ubyte value); char[] integer_to_string(short value); char[] integer_to_string(ushort value); char[] integer_to_string(int value); char[] integer_to_string(uint value); char[] integer_to_string(long value); char[] integer_to_string(ulong value); and I want to implement in C++ such as the following (pseudo-code, obviously): D_array_char_t _cdecl integer_to_string(uint32_t value) { D_array_char_t result = create a D char array of 10 elements: enough for "4294967295" do the conversion from value into result return result; } The issues I need to understand are: 1. what is D_array_char_t? 2. How do I allocate an instance of D_array_char_t? 3. How do I allocate the contents that D_array_char_t holds, the payload in other words? (This assumes that D_array_char_t is a {length + pointer}, which Walter's earlier post indicates) 4. How to I delete it, or place it back in the GC, in the case where I don't want it. If this is not possible, then I'm going to have to either: 1. wrap the C/C++ equivalents of what I propose in D functions, which will loose efficiency, or 2. have the functions return pointers to character arrays, which means (i) requiring client D code do deal with C arrays not D ones (which seems more than a little ugly), as well as (ii) complicating the implementation by providing non-leaking thread-specific-storage within the functions. Neither of these are attractive, especially since D has garbage collection which, if usable, would make it all nice and simple, as well as super quick! All info gratefully received. Matthew P.S. Any of you that are C/C++ User's Journal will no doubt recognise what I plan to do from my December 2002 article "Efficient Integer To String Conversions". I expect the performance gains described there to be almost completely acheivable within what I'm proposing here.
Mar 21 2003
Array storage is described under "memory model" in documentation.P.S. Any of you that are C/C++ User's Journal will no doubt recognise what I plan to do from my December 2002 article "Efficient Integer To String Conversions". I expect the performance gains described there to be almost completely acheivable within what I'm proposing here.I haven't read it, but ... isn't it also doable in D? If not, then why? So if the functions are not exactly huge, consider writing them directly in D. I have tried converting code from C: it doesn't take much time. As to allocating memory using garbage collector, i have looked at the library source. The garbage collector instance _gc is being initialised by gc_init() in gc2\gc.d, and you can call its allocator like "ptr = _gc.malloc(amount);" - from the D code. This is not gonna work from C. Generally, calling it doesn't make sense since you should use new operator in D code, and not rely onto obscure implementation details. It seems to me, that you should wrap the new operator into a extern(C) D function, and compile it with optimisations - hoping it gets everything inlined. -i.
Mar 22 2003
"Ilya Minkov" <midiclub 8ung.at> wrote in message news:b5i75a$2pim$1 digitaldaemon.com...Array storage is described under "memory model" in documentation.Thanks. Will check it out there. :)what IP.S. Any of you that are C/C++ User's Journal will no doubt recognisealmostplan to do from my December 2002 article "Efficient Integer To String Conversions". I expect the performance gains described there to beI'm not sure whether D's template model will lend itself as readily. (I'm not saying it won't, I simply don't know.) Also, I don't what to have to do that. Simply, I don't want to repeat the considerable effort, when I could implement as I've described. More broadly, surely no-one doubts that this kind of requirement will become more and more prevalent? Even the execrably pointer-phobic Java provides the JNI for this interfacing when necessary. I guess my question can be simply boiled down to: Is the a D Native Interface? If not, can we have one? If not, how does D expect people to integrate very significant peices of C/C++/whatever code into D. There are tasks large enough that they would likely be dissuaded from using D if told they must port. And porting is not straightforward, and is *not* an error-proof exercise.completely acheivable within what I'm proposing here.I haven't read it, but ... isn't it also doable in D? If not, then why? So if the functions are not exactly huge, consider writing them directly in D. I have tried converting code from C: it doesn't take much time.As to allocating memory using garbage collector, i have looked at the library source. The garbage collector instance _gc is being initialised by gc_init() in gc2\gc.d, and you can call its allocator like "ptr = _gc.malloc(amount);" - from the D code. This is not gonna work from C. Generally, calling it doesn't make sense since you should use new operator in D code, and not rely onto obscure implementation details. It seems to me, that you should wrap the new operator into a extern(C) D function, and compile it with optimisations - hoping it gets everything inlined. -i.
Mar 22 2003
"Matthew Wilson" <dmd synesis.com.au> wrote in message news:b5igaj$2vs5$1 digitaldaemon.com...More broadly, surely no-one doubts that this kind of requirement willbecomemore and more prevalent? Even the execrably pointer-phobic Java providestheJNI for this interfacing when necessary. I guess my question can be simply boiled down to: Is the a D Native Interface? If not, can we have one? If not, how does D expect people to integrate very significant peices of C/C++/whatever code into D. There are tasks large enough that they would likely be dissuaded from using D if told they must port. And porting isnotstraightforward, and is *not* an error-proof exercise.I don't really understand the problem. D functions can be called from C by declaring the D function as extern (C). Then, it uses C calling conventions and name mangling: ----- foo.d ------------ extern (C) int myfunc(int x) { return x + 1; } ------ bar.c ------------ extern int myfunc(int x); ... i = myfunc(3); ... ----------------------------
Mar 24 2003
As I said in the earlier post, I want to do this D_array_char_t _cdecl integer_to_string(uint32_t value) { D_array_char_t result = create a D char array of 10 elements: enough for "4294967295" do the conversion from value into result return result; } The D functions I want are - allocate a char[] array - pass that same array back to the D GC if the logic of the C++ function dictates that an error has occurred. (If this is not necesary, and the GC automatically detects unused blocks, that's fine) In an earlier post you said the array type looks like struct Array { int length; void *data; }; so let's go with that. Hence, in my C++ source I might want to do something like (of course, I wouldn't use sprintf, but it suffices for this debate): // fastconvert.cpp extern "C" Array integer_to_string(uint32_t value) { Array result = _D_allocate_char_array(10); if(result.data != NULL) { sprintf(static_cast<char*>(result.data), "%d", value); } if(some condition or other) { _D_return_to_GC(result); } return result; } So the question is, what is _D_allocate_char_array() ? Can I simply do something like Array result; result.length = 10; result.data = _D_allocate(10); in which case, my question is what is _D_allocate()? Also, how do I declare integer_to_string() in the D file? Is it like // fastconvert.d module conversion; char[] integer_to_string(uint value); How does the linker know that the Array returned in C++ is the same as the char[] in the D, and not, for example, byte[] or double[] or whatever? This is further complicated by the fact that I want to provide 8 overloads of integer_to_string (for the eight integral types), and want the corresponding 8 D functions. How can extern "C" Array integer_to_string(sint8_t value) extern "C" Array integer_to_string(uint8_t value) extern "C" Array integer_to_string(sint16_t value) extern "C" Array integer_to_string(uint16_t value) extern "C" Array integer_to_string(sint32_t value) extern "C" Array integer_to_string(uint32_t value) extern "C" Array integer_to_string(sint64_t value) extern "C" Array integer_to_string(uint64_t value) be tied up to char[] integer_to_string(byte value); char[] integer_to_string(ubyte value); char[] integer_to_string(short value); char[] integer_to_string(ushort value); char[] integer_to_string(int value); char[] integer_to_string(uint value); char[] integer_to_string(long value); char[] integer_to_string(ulong value); ? "Walter" <walter digitalmars.com> wrote in message news:b5o2vk$k5u$1 digitaldaemon.com..."Matthew Wilson" <dmd synesis.com.au> wrote in message news:b5igaj$2vs5$1 digitaldaemon.com...simplyMore broadly, surely no-one doubts that this kind of requirement willbecomemore and more prevalent? Even the execrably pointer-phobic Java providestheJNI for this interfacing when necessary. I guess my question can beconventionsboiled down to: Is the a D Native Interface? If not, can we have one? If not, how does D expect people to integrate very significant peices of C/C++/whatever code into D. There are tasks large enough that they would likely be dissuaded from using D if told they must port. And porting isnotstraightforward, and is *not* an error-proof exercise.I don't really understand the problem. D functions can be called from C by declaring the D function as extern (C). Then, it uses C callingand name mangling: ----- foo.d ------------ extern (C) int myfunc(int x) { return x + 1; } ------ bar.c ------------ extern int myfunc(int x); ... i = myfunc(3); ... ----------------------------
Mar 24 2003
"Matthew Wilson" <dmd synesis.com.au> wrote in message news:b5o751$ne7$1 digitaldaemon.com...So the question is, what is _D_allocate_char_array() ? Can I simply do something like Array result; result.length = 10; result.data = _D_allocate(10); in which case, my question is what is _D_allocate()?Create a function in D: extern (C) void *_D_allocate(int i) { return new byte[i]; } and then call _D_allocate(10) from your C code.Also, how do I declare integer_to_string() in the D file? Is it like // fastconvert.d module conversion; char[] integer_to_string(uint value); How does the linker know that the Array returned in C++ is the same as the char[] in the D, and not, for example, byte[] or double[] or whatever?The linker has no concept of function return types. Therefore, like in C++, D functions are 'mangled' with the type info. If you run obj2asm on the .obj files, you'll see the mangling. However, C functions are not mangled, therefore C functions cannot be overloaded.This is further complicated by the fact that I want to provide 8 overloads of integer_to_string (for the eight integral types), and want the corresponding 8 D functions. How can extern "C" Array integer_to_string(sint8_t value) extern "C" Array integer_to_string(uint8_t value) extern "C" Array integer_to_string(sint16_t value) extern "C" Array integer_to_string(uint16_t value) extern "C" Array integer_to_string(sint32_t value) extern "C" Array integer_to_string(uint32_t value) extern "C" Array integer_to_string(sint64_t value) extern "C" Array integer_to_string(uint64_t value) be tied up to char[] integer_to_string(byte value); char[] integer_to_string(ubyte value); char[] integer_to_string(short value); char[] integer_to_string(ushort value); char[] integer_to_string(int value); char[] integer_to_string(uint value); char[] integer_to_string(long value); char[] integer_to_string(ulong value); ?C does not support function overloading, therefore this cannot work. You'll have to give the functions different names.
Mar 25 2003
overloadsThis is further complicated by the fact that I want to provide 8You'llof integer_to_string (for the eight integral types), and want the corresponding 8 D functions. How can extern "C" Array integer_to_string(sint8_t value) extern "C" Array integer_to_string(uint8_t value) extern "C" Array integer_to_string(sint16_t value) extern "C" Array integer_to_string(uint16_t value) extern "C" Array integer_to_string(sint32_t value) extern "C" Array integer_to_string(uint32_t value) extern "C" Array integer_to_string(sint64_t value) extern "C" Array integer_to_string(uint64_t value) be tied up to char[] integer_to_string(byte value); char[] integer_to_string(ubyte value); char[] integer_to_string(short value); char[] integer_to_string(ushort value); char[] integer_to_string(int value); char[] integer_to_string(uint value); char[] integer_to_string(long value); char[] integer_to_string(ulong value); ?C does not support function overloading, therefore this cannot work.have to give the functions different names.He wanted using C++, IIRC. Sab
Mar 25 2003
"Luna Kid" <lunakid neuropolis.org> wrote in message news:b5q0ef$1tes$1 digitaldaemon.com...He wanted using C++, IIRC.Ok, but D doesn't support the C++ name mangling, so you're still back to providing different names.
Apr 03 2003