Re: Request Assistance Calling D from C++: weird visibility issue inside struct and namespace
On Wednesday, 8 November 2017 at 08:42:01 UTC, Petar Kirov [ZombineDev] wrote: Walter has recently been working on improving the C++ mangling, so be sure to test the latest dmd nightly build and if that doesn't work be sure to file bug report(s). https://github.com/dlang/dmd/pull/7250 https://github.com/dlang/dmd/pull/7259 https://github.com/dlang/dmd/pull/7272 Done: https://issues.dlang.org/show_bug.cgi?id=17975
Re: Request Assistance Calling D from C++: weird visibility issue inside struct and namespace
On Wednesday, 8 November 2017 at 15:12:05 UTC, MGW wrote: The useful material. https://www.youtube.com/watch?v=HTgJaRRfLPk Useful indeed, thank you.
Re: Request Assistance Calling D from C++: weird visibility issue inside struct and namespace
On Wednesday, 8 November 2017 at 06:34:27 UTC, Andrew Edwards wrote: I'm having a little bit of problem calling D code from C++ and would appreciate some assistance. First, given the following C++ program wich compiles, links, and runs without any problem: The useful material. https://www.youtube.com/watch?v=HTgJaRRfLPk
Re: Request Assistance Calling D from C++: weird visibility issue inside struct and namespace
On Wednesday, 8 November 2017 at 07:55:02 UTC, Andrew Edwards wrote: On Wednesday, 8 November 2017 at 07:30:34 UTC, evilrat wrote: On Wednesday, 8 November 2017 at 06:34:27 UTC, Andrew Edwards just using fully qualified name didn't make it? void call_cpp() { ::foo("do great things"); // calling global foo return; } No, it did not. Are you sure you put it in a namespace in C++ too? Yes. That wasn't the issue otherwise there might be some name mangling incompatibility that probably worth filling a bug report That's the one. Thanks to the hint form, Nicholas Wilson, I was able to track it down and resolve it with a call to pragma(mangle). -Andrew Walter has recently been working on improving the C++ mangling, so be sure to test the latest dmd nightly build and if that doesn't work be sure to file bug report(s). https://github.com/dlang/dmd/pull/7250 https://github.com/dlang/dmd/pull/7259 https://github.com/dlang/dmd/pull/7272
Re: Request Assistance Calling D from C++: weird visibility issue inside struct and namespace
On Wednesday, 8 November 2017 at 07:30:34 UTC, evilrat wrote: On Wednesday, 8 November 2017 at 06:34:27 UTC, Andrew Edwards just using fully qualified name didn't make it? void call_cpp() { ::foo("do great things"); // calling global foo return; } No, it did not. Are you sure you put it in a namespace in C++ too? Yes. That wasn't the issue otherwise there might be some name mangling incompatibility that probably worth filling a bug report That's the one. Thanks to the hint form, Nicholas Wilson, I was able to track it down and resolve it with a call to pragma(mangle). -Andrew
Re: Request Assistance Calling D from C++: weird visibility issue inside struct and namespace
On Wednesday, 8 November 2017 at 07:06:39 UTC, Nicholas Wilson wrote: On Wednesday, 8 November 2017 at 06:34:27 UTC, Andrew Edwards wrote: I'm having a little bit of problem calling D code from C++ and would appreciate some assistance. First, given the following C++ program wich compiles, links, and runs without any problem: Try using `nm` on the C++ object to find out what it thinks the mangling should be. Check that against the mangling DMD produces. Tried it, and it works. Solution: nm dexample | grep foo -> returns the __C++__mangling Use it to define the function as such: pragma(mangle, "__C++__mangling") extern (C++) void foo(const char* str) { // doing great things; } Thank you so much. -Andrew
Re: Request Assistance Calling D from C++: weird visibility issue inside struct and namespace
On Wednesday, 8 November 2017 at 06:34:27 UTC, Andrew Edwards wrote: Modify example.cpp to: == // example.cpp #include "example.h" namespace SomeApi {} struct SomeStruct {} void call_cpp() { foo("do great things"); return; } == Compile and link and you have D program calling, calling C++, which in turn calls D. My problem is that I've encountered an issue where this does not work: when the function is being called from a namespace or local scope in C++, the linker cannot find the definition. For example: just using fully qualified name didn't make it? void call_cpp() { ::foo("do great things"); // calling global foo return; } In a last-ditch effort, I placed all of these definitions into dexample.d and, it compiled, but still filed to linking: Are you sure you put it in a namespace in C++ too? otherwise there might be some name mangling incompatibility that probably worth filling a bug report
Re: Request Assistance Calling D from C++: weird visibility issue inside struct and namespace
On Wednesday, 8 November 2017 at 06:34:27 UTC, Andrew Edwards wrote: I'm having a little bit of problem calling D code from C++ and would appreciate some assistance. First, given the following C++ program wich compiles, links, and runs without any problem: Try using `nm` on the C++ object to find out what it thinks the mangling should be. Check that against the mangling DMD produces.
Request Assistance Calling D from C++: weird visibility issue inside struct and namespace
I'm having a little bit of problem calling D code from C++ and would appreciate some assistance. First, given the following C++ program wich compiles, links, and runs without any problem: == // example.h SOME_API void foo(const char* str); // example.cpp #include "example.h" namespace SomeApi {} struct SomeStruct {} int main() { foo("do great things"); return 0; } void foo(const char* str) { // doing great things; } == Modify example.cpp to: == // example.cpp #include "example.h" namespace SomeApi {} struct SomeStruct {} void call_cpp() { foo("do great things"); return; } == Then create example.d: == void main() { call_cpp(); } extern (C++) void foo(const char* str) { // doing great things; } == Compile and link and you have D program calling, calling C++, which in turn calls D. My problem is that I've encountered an issue where this does not work: when the function is being called from a namespace or local scope in C++, the linker cannot find the definition. For example: void SomeApi::CallFromNamespace() { foo("do great things"); } or void SomeStruct::CallFromStruct() { foo("do great things"); } In a last-ditch effort, I placed all of these definitions into dexample.d and, it compiled, but still filed to linking: extern (C) void foo(const char* str) { // doing great things; } extern (C++) void foo(const char* str) { // doing great things; } extern (C++, SOME_API) void foo(const char* str) { // doing great things; } extern (D) void foo(const char* str) { // doing great things; } extern void foo(const char* str) { // doing great things; } void foo(const char* str) { // doing great things; } === Linker error returned: === Undefined symbols for architecture x86_64: "foo()", referenced from: SomeStruct::CallFromStruct() in example.o SomeApi::CallFromNamespace() in example.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation) make: *** [dexample] Error 1 Using DMD v2.077.0 on macOS High Sierra -Andrew
Re: Undefined Reference calling D from C using static linking
On 2017-03-23 13:26, Nicholas Wilson wrote: Getting dmd to do the linking should work. You may wish to see what mir (github.com/libmir) does to build in it's "Better C" mode, so i'm sure it is possible, I just don't know the incantations, sorry. Perhaps someone else can help. As an ugly workaround, you can defined the "_d_dso_registry" symbol yourself. To be sure, it should match the signature in the runtime. -- /Jacob Carlborg
Re: Undefined Reference calling D from C using static linking
On Thursday, 23 March 2017 at 12:06:14 UTC, data pulverizer wrote: On Thursday, 23 March 2017 at 11:32:25 UTC, Nicholas Wilson wrote: On Thursday, 23 March 2017 at 10:49:37 UTC, data pulverizer wrote: [...] Those functions are the bounds checking function, the non unittest assert function, the unittest function an module initialisation function respectively. dmd -boundscheck=off -release should get rid of the first two, you didn't compile with -unittest so I'm not sure why the thord one is there at all. For _d_dso_registry all i can suggest is see what -betterC gets you. I just compiled `dmd -c dcode.d -betterC -boundscheck=off` (-betterC probably makes -boundscheck=off irrelevant but I threw it in as a prayer) I am still getting: ``` dcode.o:(.text.d_dso_init[.data.d_dso_rec]+0x22): undefined reference to `_d_dso_registry' collect2: error: ld returned 1 exit status ``` Getting dmd to do the linking should work. You may wish to see what mir (github.com/libmir) does to build in it's "Better C" mode, so i'm sure it is possible, I just don't know the incantations, sorry. Perhaps someone else can help.
Re: Undefined Reference calling D from C using static linking
On Thursday, 23 March 2017 at 11:32:25 UTC, Nicholas Wilson wrote: On Thursday, 23 March 2017 at 10:49:37 UTC, data pulverizer wrote: On Thursday, 23 March 2017 at 10:16:22 UTC, Nicholas Wilson wrote: It has to do with module references to druntime stuff. You can either try adding a pragma(LDC_no_module_info); //I think it is spelled correctly. or you can use ldc to link and it will link druntime gcc ccode.c -c ldc2 dcode.d code.o I don't know how well that will work. Many thanks, I tried: ``` pragma(LDC_no_moduleinfo) // https://wiki.dlang.org/LDC-specific_language_changes#LDC_no_moduleinfo ``` which worked, your method of doing the final compilation using ldc2 (or dmd) also works :-) Is there a dmd equivalent for `pragma(LDC_no_module_info);`? Attempting the final compilation `gcc -o output ccode.o dcode.o` after the second stage compilation `dmd -c dcode.d` gives an error: ``` dcode.o: In function `_D5dcode7__arrayZ': dcode.d:(.text._D5dcode7__arrayZ+0x23): undefined reference to `_d_arraybounds' dcode.o: In function `_D5dcode8__assertFiZv': dcode.d:(.text._D5dcode8__assertFiZv+0x23): undefined reference to `_d_assert' dcode.o: In function `_D5dcode15__unittest_failFiZv': dcode.d:(.text._D5dcode15__unittest_failFiZv+0x23): undefined reference to `_d_unittest' dcode.o:(.text.d_dso_init[.data.d_dso_rec]+0x22): undefined reference to `_d_dso_registry' collect2: error: ld returned 1 exit status ``` ``` dmd --version DMD64 D Compiler v2.073.2 Copyright (c) 1999-2016 by Digital Mars written by Walter Bright ``` Those functions are the bounds checking function, the non unittest assert function, the unittest function an module initialisation function respectively. dmd -boundscheck=off -release should get rid of the first two, you didn't compile with -unittest so I'm not sure why the thord one is there at all. For _d_dso_registry all i can suggest is see what -betterC gets you. I just compiled `dmd -c dcode.d -betterC -boundscheck=off` (-betterC probably makes -boundscheck=off irrelevant but I threw it in as a prayer) I am still getting: ``` dcode.o:(.text.d_dso_init[.data.d_dso_rec]+0x22): undefined reference to `_d_dso_registry' collect2: error: ld returned 1 exit status ```
Re: Undefined Reference calling D from C using static linking
On Thursday, 23 March 2017 at 10:49:37 UTC, data pulverizer wrote: On Thursday, 23 March 2017 at 10:16:22 UTC, Nicholas Wilson wrote: It has to do with module references to druntime stuff. You can either try adding a pragma(LDC_no_module_info); //I think it is spelled correctly. or you can use ldc to link and it will link druntime gcc ccode.c -c ldc2 dcode.d code.o I don't know how well that will work. Many thanks, I tried: ``` pragma(LDC_no_moduleinfo) // https://wiki.dlang.org/LDC-specific_language_changes#LDC_no_moduleinfo ``` which worked, your method of doing the final compilation using ldc2 (or dmd) also works :-) Is there a dmd equivalent for `pragma(LDC_no_module_info);`? Attempting the final compilation `gcc -o output ccode.o dcode.o` after the second stage compilation `dmd -c dcode.d` gives an error: ``` dcode.o: In function `_D5dcode7__arrayZ': dcode.d:(.text._D5dcode7__arrayZ+0x23): undefined reference to `_d_arraybounds' dcode.o: In function `_D5dcode8__assertFiZv': dcode.d:(.text._D5dcode8__assertFiZv+0x23): undefined reference to `_d_assert' dcode.o: In function `_D5dcode15__unittest_failFiZv': dcode.d:(.text._D5dcode15__unittest_failFiZv+0x23): undefined reference to `_d_unittest' dcode.o:(.text.d_dso_init[.data.d_dso_rec]+0x22): undefined reference to `_d_dso_registry' collect2: error: ld returned 1 exit status ``` ``` dmd --version DMD64 D Compiler v2.073.2 Copyright (c) 1999-2016 by Digital Mars written by Walter Bright ``` Those functions are the bounds checking function, the non unittest assert function, the unittest function an module initialisation function respectively. dmd -boundscheck=off -release should get rid of the first two, you didn't compile with -unittest so I'm not sure why the thord one is there at all. For _d_dso_registry all i can suggest is see what -betterC gets you.
Re: Undefined Reference calling D from C using static linking
On Thursday, 23 March 2017 at 10:16:22 UTC, Nicholas Wilson wrote: It has to do with module references to druntime stuff. You can either try adding a pragma(LDC_no_module_info); //I think it is spelled correctly. or you can use ldc to link and it will link druntime gcc ccode.c -c ldc2 dcode.d code.o I don't know how well that will work. Many thanks, I tried: ``` pragma(LDC_no_moduleinfo) // https://wiki.dlang.org/LDC-specific_language_changes#LDC_no_moduleinfo ``` which worked, your method of doing the final compilation using ldc2 (or dmd) also works :-) Is there a dmd equivalent for `pragma(LDC_no_module_info);`? Attempting the final compilation `gcc -o output ccode.o dcode.o` after the second stage compilation `dmd -c dcode.d` gives an error: ``` dcode.o: In function `_D5dcode7__arrayZ': dcode.d:(.text._D5dcode7__arrayZ+0x23): undefined reference to `_d_arraybounds' dcode.o: In function `_D5dcode8__assertFiZv': dcode.d:(.text._D5dcode8__assertFiZv+0x23): undefined reference to `_d_assert' dcode.o: In function `_D5dcode15__unittest_failFiZv': dcode.d:(.text._D5dcode15__unittest_failFiZv+0x23): undefined reference to `_d_unittest' dcode.o:(.text.d_dso_init[.data.d_dso_rec]+0x22): undefined reference to `_d_dso_registry' collect2: error: ld returned 1 exit status ``` ``` dmd --version DMD64 D Compiler v2.073.2 Copyright (c) 1999-2016 by Digital Mars written by Walter Bright ```
Re: Undefined Reference calling D from C using static linking
On Thursday, 23 March 2017 at 09:11:28 UTC, data pulverizer wrote: I am trying to call a D function from C. Here is the D code: ``` /* dcode.d */ extern (C) nothrow @nogc @system { double multNum(double x, double y) { return x*y; } } ``` [...] It has to do with module references to druntime stuff. You can either try adding a pragma(LDC_no_module_info); //I think it is spelled correctly. or you can use ldc to link and it will link druntime gcc ccode.c -c ldc2 dcode.d code.o I don't know how well that will work.
Undefined Reference calling D from C using static linking
I am trying to call a D function from C. Here is the D code: ``` /* dcode.d */ extern (C) nothrow @nogc @system { double multNum(double x, double y) { return x*y; } } ``` Then the C code: ``` /* ccode.c */ #include #include #include extern double multNum(double x, double y); int main() { printf("output: %f", multNum(3.0, 4.0)); return 0; } ``` Then I compile with: ``` ldc2 -c dcode.d gcc -c ccode.c gcc -o output ccode.o dcode.o ``` I get the error: ``` dcode.o: In function `ldc.register_dso': dcode.d:(.text.ldc.register_dso+0x6e): undefined reference to `_d_dso_registry' collect2: error: ld returned 1 exit status ``` Compiler versions: ``` $ ldc2 --version LDC - the LLVM D compiler (1.1.0): based on DMD v2.071.2 and LLVM 3.9.1 built with LDC - the LLVM D compiler (1.1.0) Default target: x86_64-unknown-linux-gnu Host CPU: ivybridge http://dlang.org - http://wiki.dlang.org/LDC Registered Targets: x86- 32-bit X86: Pentium-Pro and above x86-64 - 64-bit X86: EM64T and AMD64 ``` ``` $ gcc --version gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609 Copyright (C) 2015 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ``` I would appreciate it if someone could point out my mistake. Thank you in advance
Re: Calling D from C, C++, Python…
On 2015-09-13 12:10, Jakob Ovrum wrote: On Linux and other ELF-using platforms, initialization and deinitialization functions could be placed in the .init and .deinit special sections, but I don't know if druntime has any convenient provisions for this. With GDC and LDC you can probably use a pragma to put functions in these sections, but I don't know if DMD has such a pragma. I don't know what the equivalent is for Apple's Mach-O shared libraries. It's supported in Mach-O as well, not sure about the section names though. -- /Jacob Carlborg
Re: Calling D from C, C++, Python…
On Sunday, 13 September 2015 at 10:10:32 UTC, Jakob Ovrum wrote: On Thursday, 10 September 2015 at 18:01:10 UTC, Russel Winder wrote: Is there an easy way of knowing when you do not have to initialize the D runtime system to call D code from, in this case, Python via a C adapter? I naïvely transformed some C++ to D, without consideration of D runtime systems, compiled it and it all worked. Which is good, but… Surely the reasonable choice is to always initialize the runtime in a sensible location? What do you gain from not initializing it, and is it really worth the effort? core.runtime has Runtime.initialize and Runtime.terminate. In a Windows DLL, it's sensible to use DllMain to call these. core.sys.windows.dll.SimpleDllMain is a mixin template that makes it easy: version(Windows) { import core.sys.windows.dll; mixin SimpleDllMain; } On Linux and other ELF-using platforms, initialization and deinitialization functions could be placed in the .init and .deinit special sections, but I don't know if druntime has any convenient provisions for this. With GDC and LDC you can probably use a pragma to put functions in these sections, but I don't know if DMD has such a pragma. I don't know what the equivalent is for Apple's Mach-O shared libraries. Note that if the host program can call into the D shared library from multiple threads, it's necessary to register those threads with the runtime as well. The DllMain solution handles this automatically, but for other systems additional handling is necessary.
Re: Calling D from C, C++, Python…
On Thursday, 10 September 2015 at 18:01:10 UTC, Russel Winder wrote: Is there an easy way of knowing when you do not have to initialize the D runtime system to call D code from, in this case, Python via a C adapter? I naïvely transformed some C++ to D, without consideration of D runtime systems, compiled it and it all worked. Which is good, but… Surely the reasonable choice is to always initialize the runtime in a sensible location? What do you gain from not initializing it, and is it really worth the effort? core.runtime has Runtime.initialize and Runtime.terminate. In a Windows DLL, it's sensible to use DllMain to call these. core.sys.windows.dll.SimpleDllMain is a mixin template that makes it easy: version(Windows) { import core.sys.windows.dll; mixin SimpleDllMain; } On Linux and other ELF-using platforms, initialization and deinitialization functions could be placed in the .init and .deinit special sections, but I don't know if druntime has any convenient provisions for this. With GDC and LDC you can probably use a pragma to put functions in these sections, but I don't know if DMD has such a pragma. I don't know what the equivalent is for Apple's Mach-O shared libraries.
Re: Calling D from C, C++, Python…
On Saturday, 12 September 2015 at 18:20:37 UTC, Brad Roberts wrote: You can get away with it in some circumstances, but it's at your own risk. Yeah, I agree.
Re: Calling D from C, C++, Python…
On 9/12/15 9:20 AM, Adam D. Ruppe via Digitalmars-d-learn wrote: On Saturday, 12 September 2015 at 09:47:55 UTC, Jacob Carlborg wrote: Well, if your D function doesn't use anything of the runtime I guess it's not necessary. Right. If you don't call into the threading system in the druntime, you should be ok. Keep in mind though that the GC uses the threads and the new expression, array literals, array append, and others use the GC. Runtime.initialize is also what calls static and module constructors... and might have responsibility for fixing up dynamic casting of class objects in a shared lib too, I'm not sure about that. But if you avoid the bulk of the runtime functions, indeed you can get away without initializing it. Just that null thread handle is likely to cause segfaults in places where you might not expect if you don't. It is best to initialize it. Lots of C libraries need an init an teardown call, so surely the Python interop provides some solution for it. idk what it would be though. I think it's safest to say (and it belongs in the spec somewhere) that executing D code before initializing the runtime results in undefined behavior, or something along those lines. You can get away with it in some circumstances, but it's at your own risk.
Re: Calling D from C, C++, Python…
On Saturday, 12 September 2015 at 09:47:55 UTC, Jacob Carlborg wrote: Well, if your D function doesn't use anything of the runtime I guess it's not necessary. Right. If you don't call into the threading system in the druntime, you should be ok. Keep in mind though that the GC uses the threads and the new expression, array literals, array append, and others use the GC. Runtime.initialize is also what calls static and module constructors... and might have responsibility for fixing up dynamic casting of class objects in a shared lib too, I'm not sure about that. But if you avoid the bulk of the runtime functions, indeed you can get away without initializing it. Just that null thread handle is likely to cause segfaults in places where you might not expect if you don't. It is best to initialize it. Lots of C libraries need an init an teardown call, so surely the Python interop provides some solution for it. idk what it would be though.
Re: Calling D from C, C++, Python…
On 2015-09-12 10:56, Russel Winder via Digitalmars-d-learn wrote: I have a small D function (C linkage) compiled to a shared object that I am calling from Python via CFFI that works fine with no D runtime initialization. Thus I have experimental evidence "always" is not entirely the case! I really need to explore the boundaries of what point you have to actually initialize the D runtime… Well, if your D function doesn't use anything of the runtime I guess it's not necessary. Example: void foo () { printf("foo\n"); } -- /Jacob Carlborg
Re: Calling D from C, C++, Python…
On Fri, 2015-09-11 at 21:50 +0200, Jacob Carlborg via Digitalmars-d -learn wrote: > On 2015-09-10 20:01, Russel Winder via Digitalmars-d-learn wrote: > > Is there an easy way of knowing when you do not have to initialize > > the > > D runtime system to call D code from, in this case, Python via a C > > adapter? > > You always need to initialize the D runtime, unless you have a D main > function. You can initialize the runtime as many times you like, > assuming you also deinitialize it the same number of times. I have a small D function (C linkage) compiled to a shared object that I am calling from Python via CFFI that works fine with no D runtime initialization. Thus I have experimental evidence "always" is not entirely the case! I really need to explore the boundaries of what point you have to actually initialize the D runtime… -- Russel. = Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.win...@ekiga.net 41 Buckmaster Roadm: +44 7770 465 077 xmpp: rus...@winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder signature.asc Description: This is a digitally signed message part
Re: Calling D from C, C++, Python…
On 2015-09-10 20:01, Russel Winder via Digitalmars-d-learn wrote: Is there an easy way of knowing when you do not have to initialize the D runtime system to call D code from, in this case, Python via a C adapter? You always need to initialize the D runtime, unless you have a D main function. You can initialize the runtime as many times you like, assuming you also deinitialize it the same number of times. -- /Jacob Carlborg
Calling D from C, C++, Python…
Is there an easy way of knowing when you do not have to initialize the D runtime system to call D code from, in this case, Python via a C adapter? I naïvely transformed some C++ to D, without consideration of D runtime systems, compiled it and it all worked. Which is good, but… -- Russel. = Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.win...@ekiga.net 41 Buckmaster Roadm: +44 7770 465 077 xmpp: rus...@winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder signature.asc Description: This is a digitally signed message part
Re: Calling D from C
On 2013-11-24 08:22, evilrat wrote: ok i find out what's your problem. here is 2 ways of solving this problem. 1) build like you do already but add to gcc call phobos lib, so it will looks like "gcc bar.c foo.o /usr/share/dmd/lib/libphobos2.a" 2) build with foo.d with "dmd foo.d -lib" which generates proper lib file with all necessary stuff from phobos and whatever. i specifically choose this order so you can think whats happened. Compiling with DMD and the -v flag shows a verbose output and exactly how DMD calls GCC to link everything. -- /Jacob Carlborg
Re: Calling D from C
On Sunday, 24 November 2013 at 07:22:37 UTC, evilrat wrote: On Sunday, 24 November 2013 at 05:25:36 UTC, CJS wrote: dmd -c foo.d gcc bar.c foo.o ok i find out what's your problem. here is 2 ways of solving this problem. 1) build like you do already but add to gcc call phobos lib, so it will looks like "gcc bar.c foo.o /usr/share/dmd/lib/libphobos2.a" 2) build with foo.d with "dmd foo.d -lib" which generates proper lib file with all necessary stuff from phobos and whatever. i specifically choose this order so you can think whats happened. That works. Thanks!
Re: Calling D from C
On Sunday, 24 November 2013 at 06:48:50 UTC, Jesse Phillips wrote: On Sunday, 24 November 2013 at 05:54:44 UTC, evilrat wrote: On Sunday, 24 November 2013 at 05:25:36 UTC, CJS wrote: bash calls: dmd -c foo.d gcc bar.c foo.o this is wrong. there should flag for building static lib which should produce foo.a which then you link with C build. There isn't anything special about .a files, they just contain multiple .o "collections" He looks to be missing an initialization of the runtime, but then again thought I read something about a trick making that not needed (at least for dynamic loading)... Someone else will have to pitch in what the correct solution is. this is not about runtime, ld(linker) reports missing symbols, so it is either x86/x64 versions mismatch, or maybe with dmd 2.064 it is necessary to mark exported symbols with "export" keyword
Re: Calling D from C
On Sunday, 24 November 2013 at 05:25:36 UTC, CJS wrote: dmd -c foo.d gcc bar.c foo.o ok i find out what's your problem. here is 2 ways of solving this problem. 1) build like you do already but add to gcc call phobos lib, so it will looks like "gcc bar.c foo.o /usr/share/dmd/lib/libphobos2.a" 2) build with foo.d with "dmd foo.d -lib" which generates proper lib file with all necessary stuff from phobos and whatever. i specifically choose this order so you can think whats happened.
Re: Calling D from C
On Sunday, 24 November 2013 at 05:54:44 UTC, evilrat wrote: On Sunday, 24 November 2013 at 05:25:36 UTC, CJS wrote: bash calls: dmd -c foo.d gcc bar.c foo.o this is wrong. there should flag for building static lib which should produce foo.a which then you link with C build. There isn't anything special about .a files, they just contain multiple .o "collections" He looks to be missing an initialization of the runtime, but then again thought I read something about a trick making that not needed (at least for dynamic loading)... Someone else will have to pitch in what the correct solution is.
Re: Calling D from C
On Sunday, 24 November 2013 at 05:25:36 UTC, CJS wrote: bash calls: dmd -c foo.d gcc bar.c foo.o this is wrong. there should flag for building static lib which should produce foo.a which then you link with C build.
Calling D from C
I haven't been able to make calling D from C on Mac OS 10.9 work. I tried the following simple example: foo.d import std.stdio; extern(C) int add(int x, int y){ return x + y; } bar.c #include int add(int , int); int main(){ int x = 1; int y = 2; char s[] = "%d + %d = %d"; printf(s, x, y, add(x,y)); } bash calls: dmd -c foo.d gcc bar.c foo.o This gives a long error, summarized as ld: symbol(s) not found for architecture x86_64 (FYI, in Mac OS 10.9 the aging gcc version has apparently been replaced with a more recent version of clang, so the above gcc call is actually some version of clang: gcc --version Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1 Apple LLVM version 5.0 (clang-500.2.79) (based on LLVM 3.3svn) Target: x86_64-apple-darwin13.0.0 Thread model: posix) Is there some way to make this work? I'd like to call D code from C, and I'm fine statically compiling the D code and linking it to C.
Re: Calling D from C++
On 2011-07-19 12:39, Loopback wrote: On 2011-07-19 05:46, Johann MacDonagh wrote: What is the best method to accomplish this, and are there any limitations with this method (do I have to allocate the class with malloc instead etc.)? Your C++ class "Base" is not compatible with your D "Foo" class. The v-tables are not guaranteed to be identical. I'm not even sure if D's thiscall is the same as C++'s thiscall. It's just not going to work. Most languages don't support this. This is why we use C bindings. Everyone supports C ;) Now, you can do something like this: struct Foo { int x; float y; } extern(C) void* GetNewFoo() { // Note: Don't use new here otherwise the GC may clean it up return cast(void*) core.memory.GC.malloc(Foo.sizeof); } extern(C) float Foo_DoSomething(Foo* foo) { return foo.x + foo.y; } extern(C) void FreeFoo(Foo* foo) { core.memory.GC.free(foo); } I haven't tried this, but something like this should work. Structs are inherently compatible between languages. Of course, you won't be able to do any kind of polymorphism. Does this help? Very interesting! This might help depends; are you able to have structures with functions? Are they still analogous if you implement them? Also, how come the class-interface inheritance didn't work to communicate with C++. Is the "Interface to C++" doc's outdated? "Calling D Virtual Functions From C++" http://www.digitalmars.com/d/2.0/cpp_interface.html I noticed that function seems to work functions with structures. Are there any restrictions worth knowing or is it just like any other structure when D and C++ communicate? Can I have private variables, public, properties etc? And just not to forget, why the C++ and interface class didn't work?
Re: Calling D from C++
On 2011-07-19 05:46, Johann MacDonagh wrote: What is the best method to accomplish this, and are there any limitations with this method (do I have to allocate the class with malloc instead etc.)? Your C++ class "Base" is not compatible with your D "Foo" class. The v-tables are not guaranteed to be identical. I'm not even sure if D's thiscall is the same as C++'s thiscall. It's just not going to work. Most languages don't support this. This is why we use C bindings. Everyone supports C ;) Now, you can do something like this: struct Foo { int x; float y; } extern(C) void* GetNewFoo() { // Note: Don't use new here otherwise the GC may clean it up return cast(void*) core.memory.GC.malloc(Foo.sizeof); } extern(C) float Foo_DoSomething(Foo* foo) { return foo.x + foo.y; } extern(C) void FreeFoo(Foo* foo) { core.memory.GC.free(foo); } I haven't tried this, but something like this should work. Structs are inherently compatible between languages. Of course, you won't be able to do any kind of polymorphism. Does this help? Very interesting! This might help depends; are you able to have structures with functions? Are they still analogous if you implement them? Also, how come the class-interface inheritance didn't work to communicate with C++. Is the "Interface to C++" doc's outdated? "Calling D Virtual Functions From C++" http://www.digitalmars.com/d/2.0/cpp_interface.html
Re: Calling D from C++
On 7/18/2011 11:52 PM, Andrej Mitrovic wrote: See I tried using dumpbin, but apparently I wiped it from my PATH so I had to rely on DLL Export viewer (because I'm lazy and it had an icon on my desktop!) which doesn't even show this. I had a hunch that was happening behind the scenes. Thanks for the info regardless hehe. If you open a Visual Studio Command Prompt it should be in your PATH. Also, you won't see the internal symbol name unless you have pdb symbols in the same directory as the DLL (VisualD converts the symbols for me, which is why I saw it).
Re: Calling D from C++
Uhh, I tried using ASM to simulate the thiscall calling convention, it didn't go all to well. :) A wrapper C++ DLL that exposes a C interface was my workaround. Here's a page that talks about some problems with passing objects via DLLs: http://www.prowiki.org/wiki4d/wiki.cgi?BestPractices/DLL
Re: Calling D from C++
On 7/19/11, Johann MacDonagh wrote: > If you export it like this, it will be exported as the C++ mangled name. > If you have extern(C) it will be cdecl "_SetInt" and extern(Windows) > will be stdcall "_SetInt@4". Right, that's all pretty standard stuff. :) > >> I don't know why, but if you use a .def file instead of `export` the >> function will be exported as a C function with no name mangling. > > If you look at dumpbin /exports you'll see something like this: > > ordinal hint RVA name > >10 306C SetInt = ?SetInt@@YAXPAH@Z (void __cdecl > SetInt(int *)) > > So the symbol still has C++ name mangling but its exported as whatever > name you want. > See I tried using dumpbin, but apparently I wiped it from my PATH so I had to rely on DLL Export viewer (because I'm lazy and it had an icon on my desktop!) which doesn't even show this. I had a hunch that was happening behind the scenes. Thanks for the info regardless hehe.
Re: Calling D from C++
On 7/18/2011 11:27 PM, Loopback wrote: On 2011-07-19 04:40, Andrej Mitrovic wrote: You have several problems. extern(C++) only specifies the calling convention, not the visibility of the symbol. To export the symbol, list it in a .def file or mark the function with export in the module itself, ala: export extern(C++) void SetInt(int * foo) {} I don't know why, but if you use a .def file instead of `export` the function will be exported as a C function with no name mangling. Anyway, use a .def file like the one below and pass it to DMD while compiling the DLL, and it should be exported with that name (and change the string "mydll.dll" of course): LIBRARY "mydll.dll" DESCRIPTION 'My DLL written in D' EXETYPE NT SUBSYSTEM WINDOWS CODE PRELOAD DISCARDABLE DATA WRITE EXPORTS SetInt ATA.lib is probably the autogenerated import library which is useful for implicit linking. Seems as if this fixed it, thank you! I want to ask though how I am supposed to go about to enable class communication. For example; if I define a interface, and inherit this interface in a class, C++ can use these class functions by defining a analogous class (instead of interface) with virtual functions. If I create a class dynamically on the heap (in my dll), and then make a function that c++ can call to receive this object, how should I proceed then? extern(C++) interface Base { int Test(); } class Foo : Base { public: extern(C++) int Test() { return 5; } } export extern(C++) void GetObject(Base base) { Foo temp = new Foo; base = Foo; } This is just a example to explain what I want to accomplish. One problem with this code, is that a memory exception is thrown on the C++ side if this function is called, whenever I use the "new" operator. Is this because it's a export/extern function? // C++ Code class Base { public: virtual int Test(void); }; What is the best method to accomplish this, and are there any limitations with this method (do I have to allocate the class with malloc instead etc.)? Your C++ class "Base" is not compatible with your D "Foo" class. The v-tables are not guaranteed to be identical. I'm not even sure if D's thiscall is the same as C++'s thiscall. It's just not going to work. Most languages don't support this. This is why we use C bindings. Everyone supports C ;) Now, you can do something like this: struct Foo { int x; float y; } extern(C) void* GetNewFoo() { // Note: Don't use new here otherwise the GC may clean it up return cast(void*) core.memory.GC.malloc(Foo.sizeof); } extern(C) float Foo_DoSomething(Foo* foo) { return foo.x + foo.y; } extern(C) void FreeFoo(Foo* foo) { core.memory.GC.free(foo); } I haven't tried this, but something like this should work. Structs are inherently compatible between languages. Of course, you won't be able to do any kind of polymorphism. Does this help?
Re: Calling D from C++
On 2011-07-19 04:40, Andrej Mitrovic wrote: You have several problems. extern(C++) only specifies the calling convention, not the visibility of the symbol. To export the symbol, list it in a .def file or mark the function with export in the module itself, ala: export extern(C++) void SetInt(int * foo) {} I don't know why, but if you use a .def file instead of `export` the function will be exported as a C function with no name mangling. Anyway, use a .def file like the one below and pass it to DMD while compiling the DLL, and it should be exported with that name (and change the string "mydll.dll" of course): LIBRARY "mydll.dll" DESCRIPTION 'My DLL written in D' EXETYPE NT SUBSYSTEM WINDOWS CODEPRELOAD DISCARDABLE DATAWRITE EXPORTS SetInt ATA.lib is probably the autogenerated import library which is useful for implicit linking. Seems as if this fixed it, thank you! I want to ask though how I am supposed to go about to enable class communication. For example; if I define a interface, and inherit this interface in a class, C++ can use these class functions by defining a analogous class (instead of interface) with virtual functions. If I create a class dynamically on the heap (in my dll), and then make a function that c++ can call to receive this object, how should I proceed then? extern(C++) interface Base { int Test(); } class Foo : Base { public: extern(C++) int Test() { return 5; } } export extern(C++) void GetObject(Base base) { Foo temp = new Foo; base = Foo; } This is just a example to explain what I want to accomplish. One problem with this code, is that a memory exception is thrown on the C++ side if this function is called, whenever I use the "new" operator. Is this because it's a export/extern function? // C++ Code class Base { public: virtual int Test(void); }; What is the best method to accomplish this, and are there any limitations with this method (do I have to allocate the class with malloc instead etc.)?
Re: Calling D from C++
On 7/18/2011 10:40 PM, Andrej Mitrovic wrote: You have several problems. extern(C++) only specifies the calling convention, not the visibility of the symbol. To export the symbol, list it in a .def file or mark the function with export in the module itself, ala: export extern(C++) void SetInt(int * foo) {} If you export it like this, it will be exported as the C++ mangled name. If you have extern(C) it will be cdecl "_SetInt" and extern(Windows) will be stdcall "_SetInt@4". I don't know why, but if you use a .def file instead of `export` the function will be exported as a C function with no name mangling. If you look at dumpbin /exports you'll see something like this: ordinal hint RVA name 10 306C SetInt = ?SetInt@@YAXPAH@Z (void __cdecl SetInt(int *)) So the symbol still has C++ name mangling but its exported as whatever name you want.
Re: Calling D from C++
You have several problems. extern(C++) only specifies the calling convention, not the visibility of the symbol. To export the symbol, list it in a .def file or mark the function with export in the module itself, ala: export extern(C++) void SetInt(int * foo) {} I don't know why, but if you use a .def file instead of `export` the function will be exported as a C function with no name mangling. Anyway, use a .def file like the one below and pass it to DMD while compiling the DLL, and it should be exported with that name (and change the string "mydll.dll" of course): LIBRARY "mydll.dll" DESCRIPTION 'My DLL written in D' EXETYPE NT SUBSYSTEM WINDOWS CODEPRELOAD DISCARDABLE DATAWRITE EXPORTS SetInt ATA.lib is probably the autogenerated import library which is useful for implicit linking.
Re: Calling D from C++
On 2011-07-19 00:56, Johann MacDonagh wrote: On 7/18/2011 5:04 PM, Andrej Mitrovic wrote: On 7/18/11, Loopback wrote: On 2011-07-18 21:59, Andrej Mitrovic wrote: import core.dll_helper; is outdated, use import core.sys.windows.dll; And also import core.runtime; Are there any examples covering these new modules, or are the procedure the same? It's all pretty much the same as the page says. There's a DLL example in this folder: \DMD\dmd2\samples\d\mydll Looks like VisualD's DLL template needs to be updated. FWIW I was able to compile and link a D DLL with the code I copy pasted in the other message. Loopback, do you have Visual Studio on your dev box? If so you should take a look at VisualD: http://www.dsource.org/projects/visuald Let us know if you're not able to compile a D DLL. Thanks for all of your replies! It seems as if the problem was solved by using core.sys.windows.dll instead. Although I do have a bit of a problem. As I mentioned earlier I wanted to make a DLL which C++ applications could interface with. By making this possible, I have a "dll.d" file (just as the example) and a "mydll.d" file - the file which implements the dll functions. In this file, I have declared a function like this (testing purpose): extern(C++) void SetInt(int * foo) { *foo = 5; } When I compile this program with this DMD command line: dmd -ofmydll.dll -L/IMPLIB mydll.d dll.d mydll.def I get a successful compile, and a DLL file generated. For some reason, I also get a ATA.lib file, which is exactly 1.00 KB big (any ideas why)? The problem though, is related to the C++ side. I load the DLL dynamically using "LoadLibraryA" function, and then I try to load the SetInt function using GetProcAddress. The LoadLibrary function succeeds but the GetProcAddress function call fails saying that the function could not be found. typedef void (*PFGMO)(int*); void main(int argc, char ** argv) { // Function Pointer PFGMO pFGMO = NULL; HINSTANCE library; if((library = LoadLibraryA("C:\\mydll.dll")) == NULL) throw 1; bool result = (pFGMO = (PFGMO) GetProcAddress(library, "SetInt")) != NULL; // Result is zero (failed) std::cout << "Result: " << result; std::cin.get(); } How come the procedure address cannot be found and how to solve it? If of interest, this is the .def file (mydll.def) LIBRARY "mydll.dll" EXETYPE NT SUBSYSTEM WINDOWS CODE SHARED EXECUTE DATA WRITE When viewing the DLL with PE Explorer (program to explore executable files) it reports that the number of symbols are zero. Is this related to the problem perhaps?
Re: Calling D from C++
On 7/18/2011 7:08 PM, Andrej Mitrovic wrote: On 7/19/11, Johann MacDonagh wrote: FWIW I was able to compile and link a D DLL with the code I copy pasted in the other message. Maybe you're running 2.052. I think in 2.053 dll_helper disappeared, and so in 2.054: D:\dev\code\d_code\DLLTest>dmd mydll.d mydll.d(9): Error: module dll_helper is in file 'core\dll_helper.d' which cannot be read Oh wow, you're correct. I was missing with dvm and had an old version ;)
Re: Calling D from C++
On 7/19/11, Johann MacDonagh wrote: > FWIW I was able to compile and link a D DLL with the code I copy pasted > in the other message. Maybe you're running 2.052. I think in 2.053 dll_helper disappeared, and so in 2.054: D:\dev\code\d_code\DLLTest>dmd mydll.d mydll.d(9): Error: module dll_helper is in file 'core\dll_helper.d' which cannot be read
Re: Calling D from C++
On 7/18/2011 5:04 PM, Andrej Mitrovic wrote: On 7/18/11, Loopback wrote: On 2011-07-18 21:59, Andrej Mitrovic wrote: import core.dll_helper; is outdated, use import core.sys.windows.dll; And also import core.runtime; Are there any examples covering these new modules, or are the procedure the same? It's all pretty much the same as the page says. There's a DLL example in this folder: \DMD\dmd2\samples\d\mydll Looks like VisualD's DLL template needs to be updated. FWIW I was able to compile and link a D DLL with the code I copy pasted in the other message. Loopback, do you have Visual Studio on your dev box? If so you should take a look at VisualD: http://www.dsource.org/projects/visuald Let us know if you're not able to compile a D DLL.
Re: Calling D from C++
On 7/18/11, Loopback wrote: > On 2011-07-18 21:59, Andrej Mitrovic wrote: >> import core.dll_helper; is outdated, use import core.sys.windows.dll; >> And also import core.runtime; > > Are there any examples covering these new modules, or are the procedure > the same? > It's all pretty much the same as the page says. There's a DLL example in this folder: \DMD\dmd2\samples\d\mydll
Re: Calling D from C++
On 2011-07-18 21:59, Andrej Mitrovic wrote: import core.dll_helper; is outdated, use import core.sys.windows.dll; And also import core.runtime; Are there any examples covering these new modules, or are the procedure the same?
Re: Calling D from C++
import core.dll_helper; is outdated, use import core.sys.windows.dll; And also import core.runtime;
Re: Calling D from C++
On 2011-07-17 22:51, Johann MacDonagh wrote: On 7/17/2011 3:53 PM, Loopback wrote: On 2011-07-17 21:45, Loopback wrote: Hello! As of my understanding you can write usable c libraries in D by using extern(C). The problem is that I haven't found any other threads asking the same question about C++ (since extern for c++ exists as well). So I have two questions, is it possible to write a dll in D usable in c++ code, and if the answer is yes, are there any restrictions? Am I forced to use explicit memory handling, or can this be handled by the garbage collection internally by the dll etc? Sorry for mentioning this a bit late but noticed this now; http://www.digitalmars.com/d/2.0/cpp_interface.html Although if someone has own experiences or something interesting to say about the matter, please do. I think you're going to be better off defining your D routines as extern(C) and then defining the C++ headers as __cdecl (for Windows of course). C++ can, of course, link against libraries using cdecl. If you write your D DLL with the normal DllEntry (this came from VisualD): import std.c.windows.windows; import core.dll_helper; __gshared HINSTANCE g_hInst; extern (Windows) BOOL DllMain(HINSTANCE hInstance, ULONG ulReason, LPVOID pvReserved) { switch (ulReason) { case DLL_PROCESS_ATTACH: g_hInst = hInstance; dll_process_attach( hInstance, true ); break; case DLL_PROCESS_DETACH: dll_process_detach( hInstance, true ); break; case DLL_THREAD_ATTACH: dll_thread_attach( true, true ); break; case DLL_THREAD_DETACH: dll_thread_detach( true, true ); break; } return true; } Then as soon as your DLL is loaded the D runtime will start. Any memory allocated in the D DLL will be garbage collected as you'd imagine. Obviously, it's not going to free any memory allocated in your C++ code ;) Thank you for your reply! I've written a C++ wrapper which communicates with D function but I have stumbled upon an error. With the code win32 DLL code on the digitalmars webpage (and yours) I receive linker errors: Error 42: Symbol Undefined _D4core10dll_helper18dll_process_detachFT4core3sys7w indows7windows6HANDLEbZv Error 42: Symbol Undefined _D4core10dll_helper18dll_process_attachFT4core3sys7w indows7windows6HANDLEbPvPvPvPiZb Error 42: Symbol Undefined _D4core13thread_helper12__ModuleInfoZ From my experience ModuleInfo undefined is often caused by not supplying a required source file to the linker, but since I only use functions from the library, I shouldn't be required to do that. Any tips?
Re: Calling D from C++
On 7/17/2011 3:53 PM, Loopback wrote: On 2011-07-17 21:45, Loopback wrote: Hello! As of my understanding you can write usable c libraries in D by using extern(C). The problem is that I haven't found any other threads asking the same question about C++ (since extern for c++ exists as well). So I have two questions, is it possible to write a dll in D usable in c++ code, and if the answer is yes, are there any restrictions? Am I forced to use explicit memory handling, or can this be handled by the garbage collection internally by the dll etc? Sorry for mentioning this a bit late but noticed this now; http://www.digitalmars.com/d/2.0/cpp_interface.html Although if someone has own experiences or something interesting to say about the matter, please do. I think you're going to be better off defining your D routines as extern(C) and then defining the C++ headers as __cdecl (for Windows of course). C++ can, of course, link against libraries using cdecl. If you write your D DLL with the normal DllEntry (this came from VisualD): import std.c.windows.windows; import core.dll_helper; __gshared HINSTANCE g_hInst; extern (Windows) BOOL DllMain(HINSTANCE hInstance, ULONG ulReason, LPVOID pvReserved) { switch (ulReason) { case DLL_PROCESS_ATTACH: g_hInst = hInstance; dll_process_attach( hInstance, true ); break; case DLL_PROCESS_DETACH: dll_process_detach( hInstance, true ); break; case DLL_THREAD_ATTACH: dll_thread_attach( true, true ); break; case DLL_THREAD_DETACH: dll_thread_detach( true, true ); break; } return true; } Then as soon as your DLL is loaded the D runtime will start. Any memory allocated in the D DLL will be garbage collected as you'd imagine. Obviously, it's not going to free any memory allocated in your C++ code ;)
Re: Calling D from C++
On 2011-07-17 21:45, Loopback wrote: Hello! As of my understanding you can write usable c libraries in D by using extern(C). The problem is that I haven't found any other threads asking the same question about C++ (since extern for c++ exists as well). So I have two questions, is it possible to write a dll in D usable in c++ code, and if the answer is yes, are there any restrictions? Am I forced to use explicit memory handling, or can this be handled by the garbage collection internally by the dll etc? Sorry for mentioning this a bit late but noticed this now; http://www.digitalmars.com/d/2.0/cpp_interface.html Although if someone has own experiences or something interesting to say about the matter, please do.
Calling D from C++
Hello! As of my understanding you can write usable c libraries in D by using extern(C). The problem is that I haven't found any other threads asking the same question about C++ (since extern for c++ exists as well). So I have two questions, is it possible to write a dll in D usable in c++ code, and if the answer is yes, are there any restrictions? Am I forced to use explicit memory handling, or can this be handled by the garbage collection internally by the dll etc?