www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Calling a D function from C

reply Carlo <carlo.lucibello gmail.com> writes:
Sorry if I bother you again with this probably silly problem. Here is 
the point. I want to call the D function "fun" from a .c file:

\\file libforc.d
extern (C) int fun(int x,int y){
         return x;
}
\\EOF

\\file ctest.c
#include <stdio.h>

int fun(int,int);

int main(int argc, char* argv[])
{
      printf("%d",fun(2,3));

      return 0;
}
\\EOF

This what I get trying to compile the .c file:

$ dmd libforc.d -c
$ gcc libforc.o ctest.c -m32
libforc.o: In function `no symbol':
libforc.d:(.text+0x8): undefined reference to `_Dmodule_ref'
collect2: ld returned 1 exit status

What did I miss?
Nov 12 2010
parent reply Michal Minich <michal.minich gmail.com> writes:
V Fri, 12 Nov 2010 16:14:30 +0100, Carlo wrote:

 Sorry if I bother you again with this probably silly problem. Here is
 the point. I want to call the D function "fun" from a .c file:
 
 \\file libforc.d
 extern (C) int fun(int x,int y){
          return x;
 }
 \\EOF
 
 \\file ctest.c
 #include <stdio.h>
 
 int fun(int,int);
 
 int main(int argc, char* argv[])
 {
       printf("%d",fun(2,3));
 
       return 0;
 }
 \\EOF
 
 This what I get trying to compile the .c file:
 
 $ dmd libforc.d -c
 $ gcc libforc.o ctest.c -m32
 libforc.o: In function `no symbol':
 libforc.d:(.text+0x8): undefined reference to `_Dmodule_ref' collect2:
 ld returned 1 exit status
 
 What did I miss?

You probably need to include phobos library in gcc command line.
Nov 12 2010
next sibling parent reply Carlo <carlo.lucibello gmail.com> writes:
On 12/11/2010 16:19, Michal Minich wrote:
 V Fri, 12 Nov 2010 16:14:30 +0100, Carlo wrote:

 Sorry if I bother you again with this probably silly problem. Here is
 the point. I want to call the D function "fun" from a .c file:

 \\file libforc.d
 extern (C) int fun(int x,int y){
           return x;
 }
 \\EOF

 \\file ctest.c
 #include<stdio.h>

 int fun(int,int);

 int main(int argc, char* argv[])
 {
        printf("%d",fun(2,3));

        return 0;
 }
 \\EOF

 This what I get trying to compile the .c file:

 $ dmd libforc.d -c
 $ gcc libforc.o ctest.c -m32
 libforc.o: In function `no symbol':
 libforc.d:(.text+0x8): undefined reference to `_Dmodule_ref' collect2:
 ld returned 1 exit status

 What did I miss?

You probably need to include phobos library in gcc command line.

Thanks for the reply. How do I do that? adding -lphobos doesn't work. Phobos sources seem to be in /src/phobos
Nov 12 2010
parent Carlo <carlo.lucibello gmail.com> writes:
On 13/11/2010 14:20, Simen kjaeraas wrote:
 Michal Minich <michal.minich gmail.com> wrote:

 first: extern (C) means that the function 'fun' is not defined in D, but
 in C.

Wrong. It means the function has C calling convention. If it has a body, it is defined in D, and can be called from C (and D). If not, it is defined elsewhere, and can be called from D.

it, so I can't figure out compiler's instruction.
Nov 14 2010
prev sibling next sibling parent Michal Minich <michal.minich gmail.com> writes:
On Sat, 13 Nov 2010 00:00:00 +0100, Carlo wrote:

 On 12/11/2010 16:19, Michal Minich wrote:
 V Fri, 12 Nov 2010 16:14:30 +0100, Carlo wrote:

 Sorry if I bother you again with this probably silly problem. Here is
 the point. I want to call the D function "fun" from a .c file:

 \\file libforc.d
 extern (C) int fun(int x,int y){
           return x;
 }
 \\EOF

 \\file ctest.c
 #include<stdio.h>

 int fun(int,int);

 int main(int argc, char* argv[])
 {
        printf("%d",fun(2,3));

        return 0;
 }
 \\EOF

 This what I get trying to compile the .c file:

 $ dmd libforc.d -c
 $ gcc libforc.o ctest.c -m32
 libforc.o: In function `no symbol':
 libforc.d:(.text+0x8): undefined reference to `_Dmodule_ref' collect2:
 ld returned 1 exit status

 What did I miss?

You probably need to include phobos library in gcc command line.

Thanks for the reply. How do I do that? adding -lphobos doesn't work. Phobos sources seem to be in /src/phobos

Sorry, this was a bad advice. first: extern (C) means that the function 'fun' is not defined in D, but in C. So you can call it from D. like: //file.d extern (C) int fun(int x,int y); void main () { writeln ( foo() ); } //file.c int fun(int x,int y){ return x; } you can then compile C file in gcc to generate .o file, which can be used with dmd. But you want the opposite direction, which I'm not sure is possible, at least in one executable. You should probably generate dynamic link library in D and then use it in C. there is how to do it in Windows, which doesn't help you much... :( anyway, you should use word 'export' to make D functions accessible from outside.
Nov 13 2010
prev sibling next sibling parent Michal Minich <michal.minich gmail.com> writes:
On Sat, 13 Nov 2010 00:00:00 +0100, Carlo wrote:

 On 12/11/2010 16:19, Michal Minich wrote:
 V Fri, 12 Nov 2010 16:14:30 +0100, Carlo wrote:

 Sorry if I bother you again with this probably silly problem. Here is
 the point. I want to call the D function "fun" from a .c file:

 \\file libforc.d
 extern (C) int fun(int x,int y){
           return x;
 }
 \\EOF

 \\file ctest.c
 #include<stdio.h>

 int fun(int,int);

 int main(int argc, char* argv[])
 {
        printf("%d",fun(2,3));

        return 0;
 }
 \\EOF

 This what I get trying to compile the .c file:

 $ dmd libforc.d -c
 $ gcc libforc.o ctest.c -m32
 libforc.o: In function `no symbol':
 libforc.d:(.text+0x8): undefined reference to `_Dmodule_ref' collect2:
 ld returned 1 exit status

 What did I miss?

You probably need to include phobos library in gcc command line.

Thanks for the reply. How do I do that? adding -lphobos doesn't work. Phobos sources seem to be in /src/phobos

Sorry, this was a bad advice. first: extern (C) means that the function 'fun' is not defined in D, but in C. So you can call it from D. like: //file.d extern (C) int fun(int x,int y); void main () { writeln ( foo() ); } //file.c int fun(int x,int y){ return x; } you can then compile C file in gcc to generate .o file, which can be used with dmd. But you want the opposite direction, which I'm not sure is possible, at least in one executable. You should probably generate dynamic link library in D and then use it in C. there is how to do it in Windows, which doesn't help you much... :( anyway, you should use word 'export' to make D functions accessible from outside.
Nov 13 2010
prev sibling next sibling parent "Simen kjaeraas" <simen.kjaras gmail.com> writes:
Michal Minich <michal.minich gmail.com> wrote:

 first: extern (C) means that the function 'fun' is not defined in D, but
 in C.

Wrong. It means the function has C calling convention. If it has a body, it is defined in D, and can be called from C (and D). If not, it is defined elsewhere, and can be called from D. -- Simen
Nov 13 2010
prev sibling next sibling parent Michal Minich <michal.minich gmail.com> writes:
On Sat, 13 Nov 2010 14:20:05 +0100, Simen kjaeraas wrote:

 Michal Minich <michal.minich gmail.com> wrote:
 
 first: extern (C) means that the function 'fun' is not defined in D,
 but in C.

Wrong. It means the function has C calling convention. If it has a body, it is defined in D, and can be called from C (and D). If not, it is defined elsewhere, and can be called from D.

Thanks.
Nov 13 2010
prev sibling parent Carlo <carlo.lucibello gmail.com> writes:
On 12/11/2010 16:19, Michal Minich wrote:
 V Fri, 12 Nov 2010 16:14:30 +0100, Carlo wrote:

 Sorry if I bother you again with this probably silly problem. Here is
 the point. I want to call the D function "fun" from a .c file:

 \\file libforc.d
 extern (C) int fun(int x,int y){
           return x;
 }
 \\EOF

 \\file ctest.c
 #include<stdio.h>

 int fun(int,int);

 int main(int argc, char* argv[])
 {
        printf("%d",fun(2,3));

        return 0;
 }
 \\EOF

 This what I get trying to compile the .c file:

 $ dmd libforc.d -c
 $ gcc libforc.o ctest.c -m32
 libforc.o: In function `no symbol':
 libforc.d:(.text+0x8): undefined reference to `_Dmodule_ref' collect2:
 ld returned 1 exit status

 What did I miss?

You probably need to include phobos library in gcc command line.

file. Here is what I get: carlo carlo-laptop:~/d$ dmd -c libforc.d carlo carlo-laptop:~/d$ ar rcs libforc.a libforc.o carlo carlo-laptop:~/d$ gcc -L. -lforc -lphobos2 -m32 ctest.c /tmp/ccpbEtKu.o: In function `main': ctest.c:(.text+0x0): multiple definition of `main' /usr/lib/gcc/x86_64-linux-gnu/4.4.5/../../../../lib32/libphobos2.a(dmain2_503_1a5.o):src/rt/dmain2 d:(.text.main+0x0): first defined here /usr/lib/gcc/x86_64-linux-gnu/4.4.5/../../../../lib32/libphobos2. (dmain2_503_1a5.o): In function `_D2rt6dmain24mainUiPPaZi7runMainMFZv': src/rt/dmain2.d:(.text._D2rt6dmain24mainUiPPaZi7runMainMFZv+0x16): undefined reference to `_Dmain' /usr/lib/gcc/x86_64-linux-gnu/4.4.5/../../../../lib32/libphobos2.a(critical.o): In function `_STI_critical_init': critical.c:(.text+0x43): undefined reference to `pthread_mutexattr_init' critical.c:(.text+0x57): undefined reference to `pthread_mutexattr_settype'carlo carlo-laptop:~/d$ dmd -c libforc.d carlo carlo-laptop:~/d$ ar rcs libforc.a libforc.o carlo carlo-laptop:~/d$ gcc -L. -lforc -lphobos2 -m32 ctest.c /tmp/ccpbEtKu.o: In function `main': ctest.c:(.text+0x0): multiple definition of `main' /usr/lib/gcc/x86_64-linux-gnu/4.4.5/../../../../lib32/libphobos2.a(dmain2_503_1a5.o):src/rt/dmain2 d:(.text.main+0x0): first defined here /usr/lib/gcc/x86_64-linux-gnu/4.4.5/../../../../lib32/libphobos2. (dmain2_503_1a5.o): In function `_D2rt6dmain24mainUiPPaZi7runMainMFZv': src/rt/dmain2.d:(.text._D2rt6dmain24mainUiPPaZi7runMainMFZv+0x16): undefined reference to `_Dmain' /usr/lib/gcc/x86_64-linux-gnu/4.4.5/../../../../lib32/libphobos2.a(critical.o): In function `_STI_critical_init': critical.c:(.text+0x43): undefined reference to `pthread_mutexattr_init' critical.c:(.text+0x57): undefined reference to `pthread_mutexattr_settype' /usr/lib/gcc/x86_64-linux-gnu/4.4.5/../../../../lib32/libphobos2.a(monitor.o): In function `_STD_monitor_staticdtor': monitor.c:(.text+0x1dc): undefined reference to `pthread_mutexattr_destroy' /usr/lib/gcc/x86_64-linux-gnu/4.4.5/../../../../lib32/libphobos2.a(monitor.o): In function `_STI_monitor_staticctor': monitor.c:(.text+0x1f9): undefined reference to `pthread_mutexattr_init' monitor.c:(.text+0x20d): undefined reference to `pthread_mutexattr_settype' /usr/lib/gcc/x86_64-linux-gnu/4.4.5/../../../../lib32/libphobos2 a(thread_e7_258.o): In function `_D4core6thread6Thread6__dtorMFZv': src/core/thread.d:(.text._D4core6thread6Thread6__dtorMFZv+0x17): undefined reference to `pthread_detach' /usr/lib/gcc/x86_64-linux-gnu/4.4.5/../../../../lib32/libphobos2 a(thread_e7_258.o): In function `_D4core6thread6Thread5startMFZv': src/core/thread.d:(.text._D4core6thread6Thread5startMFZv+0x79): undefined reference to `pthread_attr_setstacksize' /usr/lib/gcc/x86_64-linux-gnu/4.4.5/../../../../lib32/libphobos2.a(monitor.o): In function `_STD_monitor_staticdtor': monitor.c:(.text+0x1dc): undefined reference to `pthread_mutexattr_destroy' /usr/lib/gcc/x86_64-linux-gnu/4.4.5/../../../../lib32/libphobos2.a(monitor.o): In function `_STI_monitor_staticctor': monitor.c:(.text+0x1f9): undefined reference to `pthread_mutexattr_init' monitor.c:(.text+0x20d): undefined reference to `pthread_mutexattr_settype' /usr/lib/gcc/x86_64-linux-gnu/4.4.5/../../../../lib32/libphobos2 a(thread_e7_258.o): In function `_D4core6thread6Thread6__dtorMFZv': src/core/thread.d:(.text._D4core6thread6Thread6__dtorMFZv+0x17): undefined reference to `pthread_detach' /usr/lib/gcc/x86_64-linux-gnu/4.4.5/../../../../lib32/libphobos2 a(thread_e7_258.o): In function `_D4core6thread6Thread5startMFZv': src/core/thread.d:(.text._D4core6thread6Thread5startMFZv+0x79): undefined reference to `pthread_attr_setstacksize' ................................................
Nov 14 2010