www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Calling D code from C

reply Niko Korhonen <niktheblak hotmail.com> writes:
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
parent reply Vathix <vathix dprogramming.com> writes:
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 26 2005
parent Niko Korhonen <niktheblak hotmail.com> writes:
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.
May 27 2005