View mode: basic / threaded / horizontal-split · Log in · Help
May 26, 2005
Calling D code from C
I'm playing around with an idea to make my D library partially callable
in C. Getting C and D to interface with each other is something totally
new for me, and thus I've stumbled into a weird problem.

Consider the following short programs:

ctest.d: (D code)

<code>
module ctest;

extern (C)
{
	void test()
	{
		int[] x = new int[10];
		printf("x.length: %u\n", x.length);
	}
}
</code>

ctest-c.c: (C code)

<code>
void test(void); // Declare the D function

int main()
{
	test();
	return 0;
}
</code>

The purpose is to compile the D file into an obj, compile the C file and
link it with the D obj file. When I do this using DMD/DMC in the
following way:

<code>
dmd -c ctest.d
dmc ctest-c.c ctest.obj c:\tools\dmd\lib\phobos.lib
</code>

It works correctly, but when executing ctest-c.exe, it crashes with a
trying to write to a null pointer message. Apparently the 'new' clause
in the D file causes the crash.

Should this work, or have I missed something very important in C/D
interoperability? For instance, is it forbidden to use D memory
management facilities or something like that?
May 26, 2005
Re: Calling D code from C
On Thu, 26 May 2005 16:18:21 -0400, Niko Korhonen <niktheblak@hotmail.com>  
wrote:

> I'm playing around with an idea to make my D library partially callable
> in C. Getting C and D to interface with each other is something totally
> new for me, and thus I've stumbled into a weird problem.
>
> Consider the following short programs:
>
> ctest.d: (D code)
>
> <code>
> module ctest;
>
> extern (C)
> {
> 	void test()
> 	{
> 		int[] x = new int[10];
> 		printf("x.length: %u\n", x.length);
> 	}
> }
> </code>
>
> ctest-c.c: (C code)
>
> <code>
> void test(void); // Declare the D function
>
> int main()
> {
> 	test();
> 	return 0;
> }
> </code>
>
> The purpose is to compile the D file into an obj, compile the C file and
> link it with the D obj file. When I do this using DMD/DMC in the
> following way:
>
> <code>
> dmd -c ctest.d
> dmc ctest-c.c ctest.obj c:\tools\dmd\lib\phobos.lib
> </code>
>
> It works correctly, but when executing ctest-c.exe, it crashes with a
> trying to write to a null pointer message. Apparently the 'new' clause
> in the D file causes the crash.
>
> Should this work, or have I missed something very important in C/D
> interoperability? For instance, is it forbidden to use D memory
> management facilities or something like that?

The problem is that D's main() initializes things. Using a C main()  
bypasses that startup code. Put the main() in the D file (with D extern)  
and have it call a function in the C file that you will treat as main.


(D code)

extern(C)
{
   int cmain();

   void test() { printf("test!\n"); }
}

int main()
{
   return cmain();
}


(C code)

void test(void);

int cmain(void)
{
   test();
   return 0;
}
May 27, 2005
Re: Calling D code from C
Vathix wrote:
> The problem is that D's main() initializes things. Using a C main()
> bypasses that startup code. Put the main() in the D file (with D
> extern)  and have it call a function in the C file that you will treat
> as main.

Thanks a million, that fixed the problem! BTW, is anything about this
mentioned in the docs/FAQs? I couldn't find anything when I tried to
google for this issue.
Top | Discussion index | About this forum | D home