Thread overview
Calling a D function from C
Nov 12, 2010
Carlo
Nov 12, 2010
Michal Minich
Nov 12, 2010
Carlo
Nov 13, 2010
Michal Minich
Nov 13, 2010
Simen kjaeraas
Nov 13, 2010
Michal Minich
Nov 14, 2010
Carlo
Nov 13, 2010
Michal Minich
Nov 14, 2010
Carlo
November 12, 2010
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?
November 12, 2010
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.
November 12, 2010
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
November 13, 2010
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.
November 13, 2010
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.
November 13, 2010
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
November 13, 2010
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.
November 14, 2010
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.
Actually there exist a library phobos2, but i think it's a D object 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.a(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.a(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'
................................................

November 14, 2010
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.
>
That's what I read in Andrei's TDPL, still he doesn't add anything to it, so I can't figure out compiler's instruction.