www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Header headaches part 2

reply Oliver <Oliver_member pathlink.com> writes:
1. 	app = app_new_app(cast(int)args.length, cast(char*[])args);
Here, I have to convert the argument char[][] args to char*[] because 
the function expects a char*[]. I feel the way I am doing it is wrong.

2. app_on_window_redraw(w, cast(WindowDrawFunc)&draw_ellipses);
here , WindowDrawFunc is defined in app.d as
typedef void (*WindowDrawFunc)  (Window *w, Graphics *g);
and draw_ellipses is a function that fits this type, but still I had to convert
it because the compiler complained.

When I run the compiler like above I get
ellipses.o(.data+0x30): undefined reference to `_ModuleInfo_3app'
ellipses.o(.data+0x34): undefined reference to `_ModuleInfo_8app_help'
ellipses`_....D8ellipses13draw_ellipsesFPS3app6WindowPS3app8GraphicsZv':
: undefined reference to `_D8app_help4rectFiiiiZS3app4Rect'
ellipses.o(.gnu.linkonce.t_Dmain+0x4b): In function `_Dmain':
: undefined reference to `_D8app_help4rectFiiiiZS3app4Rect'
collect2: ld returned 1 exit status

however, when I use
dmd ellipses.d app_help.d app.d -L-lapp -L-lglib -L-lX11
It compiles :
gcc ellipses.o app_help.o app.o -o ellipses -lphobos -lpthread -lm -Xlinker
-lapp -Xlinker -lglib -Xlinker -lX11

And I get an executable ellipse. Running it results in :
bash-2.05b$ ./ellipses
Segmentation fault

When I use 
dmd ellipses.d app_help.d -L-lapp -L-lglib -L-lX11 
I get

ellipses.o(.data+0x30): undefined reference to `_ModuleInfo_3app'
app_help.o(.data+0x30): undefined reference to `_ModuleInfo_3app'
collect2: ld returned 1 exit status

I really depend on u people to get this working. I would love to use D.
The graphapp lib is really nice and should be easy to convert. Maybe there
is a skilled D-hacker who wants to spent some minutes on converting the header ?
It would be a great input for the community (A lightweight C-stile API for GUIS
and image loading/saving manipulation)

Regards, Oliver
May 18 2005
parent reply "Ben Hinkle" <ben.hinkle gmail.com> writes:
"Oliver" <Oliver_member pathlink.com> wrote in message 
news:d6f2m9$1sr5$1 digitaldaemon.com...
 1. app = app_new_app(cast(int)args.length, cast(char*[])args);
 Here, I have to convert the argument char[][] args to char*[] because
 the function expects a char*[]. I feel the way I am doing it is wrong.

 2. app_on_window_redraw(w, cast(WindowDrawFunc)&draw_ellipses);
 here , WindowDrawFunc is defined in app.d as
 typedef void (*WindowDrawFunc)  (Window *w, Graphics *g);
 and draw_ellipses is a function that fits this type, but still I had to 
 convert
 it because the compiler complained.

should WindowDrawFunc be extern(C)?
 And I get an executable ellipse. Running it results in :
 bash-2.05b$ ./ellipses
 Segmentation fault

This is a good start. Run in gdb and do "bt" at the seg-v to see what the stack says. Are you allocating all the object references and things like that?
May 18 2005
parent reply Oliver <Oliver_member pathlink.com> writes:
Hello !

WindowDrawFunc() is declared as extern(c) like all functions in
the app.d file (which is a converted c-header file)

I used gdb as u explained and got the following results :
==========================================================
(gdb) file ellipses
Reading symbols from ellipses...done.
Using host libthread_db library "/lib/libthread_db.so.1".
(gdb) run
Starting program: /home/ok/source/ellipses

Program received signal SIGSEGV, Segmentation fault.
0x0804dcfb in app_new_app ()
(gdb) bt
#0  0x0804dcfb in app_new_app ()
#1  0x080f0c75 in _Dmain ()
#2  0x080f11c7 in main ()
=================================================================

Therefore, the problem lies in app_new_app() - 
extern(C) :
App *	app_new_app(int argc, char *argv[]);

I pass the correct arguments to the function, it is declared in
app.d as extern(C). Therefore, I have no good idea about whats wrong.
My only idea is that I might have to 0-terminate the argv-strings
because D strings are not 0-terminated. 
Is this a possibilty ?

Regards, Oliver


In article <d6fbdj$23qv$1 digitaldaemon.com>, Ben Hinkle says...
"Oliver" <Oliver_member pathlink.com> wrote in message 
news:d6f2m9$1sr5$1 digitaldaemon.com...
 1. app = app_new_app(cast(int)args.length, cast(char*[])args);
 Here, I have to convert the argument char[][] args to char*[] because
 the function expects a char*[]. I feel the way I am doing it is wrong.

 2. app_on_window_redraw(w, cast(WindowDrawFunc)&draw_ellipses);
 here , WindowDrawFunc is defined in app.d as
 typedef void (*WindowDrawFunc)  (Window *w, Graphics *g);
 and draw_ellipses is a function that fits this type, but still I had to 
 convert
 it because the compiler complained.

should WindowDrawFunc be extern(C)?
 And I get an executable ellipse. Running it results in :
 bash-2.05b$ ./ellipses
 Segmentation fault

This is a good start. Run in gdb and do "bt" at the seg-v to see what the stack says. Are you allocating all the object references and things like that?

May 18 2005
parent reply "Ben Hinkle" <bhinkle mathworks.com> writes:
"Oliver" <Oliver_member pathlink.com> wrote in message 
news:d6fk54$2hkj$1 digitaldaemon.com...
 Hello !

 WindowDrawFunc() is declared as extern(c) like all functions in
 the app.d file (which is a converted c-header file)

 I used gdb as u explained and got the following results :
 ==========================================================
 (gdb) file ellipses
 Reading symbols from ellipses...done.
 Using host libthread_db library "/lib/libthread_db.so.1".
 (gdb) run
 Starting program: /home/ok/source/ellipses

 Program received signal SIGSEGV, Segmentation fault.
 0x0804dcfb in app_new_app ()
 (gdb) bt
 #0  0x0804dcfb in app_new_app ()
 #1  0x080f0c75 in _Dmain ()
 #2  0x080f11c7 in main ()
 =================================================================

 Therefore, the problem lies in app_new_app() -
 extern(C) :
 App * app_new_app(int argc, char *argv[]);

 I pass the correct arguments to the function, it is declared in
 app.d as extern(C). Therefore, I have no good idea about whats wrong.
 My only idea is that I might have to 0-terminate the argv-strings
 because D strings are not 0-terminated.
 Is this a possibilty ?

yes - that is a possibility. If the code you are calling expect 0-terminated strings you need to do that explicitly by calling std.string.toStringz or something equivalent. Also note that the C declaration char*argv[] is different than the D declaration char*argv[]. The D version declares a dynamic array of pointers which isn't the same as a C array of pointers. I think you want extern(C) : App * app_new_app(int argc, char **argv); I don't think I've gotten gdb to step though D code so on Linux I use printf's to narrow down the exact problem after getting a general idea from the stack.
May 18 2005
parent reply Oliver <Oliver_member pathlink.com> writes:
In article <d6fl6l$2jej$1 digitaldaemon.com>, Ben Hinkle says...
"Oliver" <Oliver_member pathlink.com> wrote in message 
news:d6fk54$2hkj$1 digitaldaemon.com...
 Hello !

 WindowDrawFunc() is declared as extern(c) like all functions in
 the app.d file (which is a converted c-header file)

 I used gdb as u explained and got the following results :
 ==========================================================
 (gdb) file ellipses
 Reading symbols from ellipses...done.
 Using host libthread_db library "/lib/libthread_db.so.1".
 (gdb) run
 Starting program: /home/ok/source/ellipses

 Program received signal SIGSEGV, Segmentation fault.
 0x0804dcfb in app_new_app ()
 (gdb) bt
 #0  0x0804dcfb in app_new_app ()
 #1  0x080f0c75 in _Dmain ()
 #2  0x080f11c7 in main ()
 =================================================================

 Therefore, the problem lies in app_new_app() -
 extern(C) :
 App * app_new_app(int argc, char *argv[]);

 I pass the correct arguments to the function, it is declared in
 app.d as extern(C). Therefore, I have no good idea about whats wrong.
 My only idea is that I might have to 0-terminate the argv-strings
 because D strings are not 0-terminated.
 Is this a possibilty ?

yes - that is a possibility. If the code you are calling expect 0-terminated strings you need to do that explicitly by calling std.string.toStringz or something equivalent. Also note that the C declaration char*argv[] is different than the D declaration char*argv[]. The D version declares a dynamic array of pointers which isn't the same as a C array of pointers. I think you want extern(C) : App * app_new_app(int argc, char **argv); I don't think I've gotten gdb to step though D code so on Linux I use printf's to narrow down the exact problem after getting a general idea from the stack.

Hello again ! I think one problem is to convert the char[][]argv parameter of the D-main method to a char** (I changed the signature from App * app_new_app(int argc, char *argv[]); to App * app_new_app(int argc, char **argv); in app.d. Here is the code of the main method of ellipses.d to clarify things ============================================================================ int main(char[][] args) { App *app; Window *w; char** myargs; myargs = cast(char**)&args; app = app_new_app(cast(int)args.length,myargs); .. ============================================================================= The above conversion is not correct, I guess ? I tried to 0-terminate the strings but that didnt change the segfault. regards, Oliver
May 18 2005
parent reply "Ben Hinkle" <bhinkle mathworks.com> writes:
============================================================================
 int main(char[][] args)
 {
 App *app;
 Window *w;
 char** myargs;
 myargs = cast(char**)&args;
 app = app_new_app(cast(int)args.length,myargs);
 ..
 =============================================================================

Here's what I do in MinWin when to pass D's args to a C function: int main(char[][] args) { char*[] argv; argv.length = args.length; foreach (int n, char[] str; args) { argv[n] = toStringz(str); } int argc = args.length; app = app_new_app(argc,argv.ptr); }
May 18 2005
parent reply Oliver <Oliver_member pathlink.com> writes:
In article <d6g0bt$30g1$1 digitaldaemon.com>, Ben Hinkle says...
============================================================================
 int main(char[][] args)
 {
 App *app;
 Window *w;
 char** myargs;
 myargs = cast(char**)&args;
 app = app_new_app(cast(int)args.length,myargs);
 ..
 =============================================================================

Here's what I do in MinWin when to pass D's args to a C function: int main(char[][] args) { char*[] argv; argv.length = args.length; foreach (int n, char[] str; args) { argv[n] = toStringz(str); } int argc = args.length; app = app_new_app(argc,argv.ptr); }

Hello ! That helped ! Now a window is opened - and the program crashes immediately. Analysis with gdb yields : (gdb) bt #0 0x0804d869 in app_set_line_width () #1 0x080f0b27 in _D8ellipses13draw_ellipsesFPS3app6WindowPS3app8GraphicsZv () #2 0x0804cbe7 in app_do_redraw_window () #3 0x0804ceb5 in app_winproc () #4 0x0804d226 in app_wait_event () #5 0x0804d151 in app_main_loop () #6 0x080f0c6e in _Dmain () #7 0x080f1167 in main () (gdb) continue Continuing. Program terminated with signal SIGSEGV, Segmentation fault. Here is the corresponding code piece : int main(char[][] args) { App *app; Window *w; char*[] myargs; myargs.length = args.length; foreach(int n,char[] str;args) { myargs[n]=toString(str); } int argc = args.length; app = app_new_app(argc,myargs.ptr); w = app_new_window(app, rect(10,10,448,400), "Ellipses Test", STANDARD_WINDOW); app_on_window_redraw(w,cast(WindowDrawFunc)(&draw_ellipses); draw ellipses then calls app_set_line_width(). I think the problem is the way I cast draw_ellipses. WindowDrawFunc is defined as typedef void (*WindowDrawFunc) (Window *w, Graphics *g); in the converted C-header app.d . draw_ellipses is a simple method defined in ellipses.d (The main file). I hope I dont bother you and would be glad about further help. Regards, Oliver
May 18 2005
parent reply "Ben Hinkle" <ben.hinkle gmail.com> writes:
 That helped ! Now a window is opened - and the program crashes 
 immediately.
 Analysis with gdb yields :
 (gdb) bt
 #0  0x0804d869 in app_set_line_width ()
 #1  0x080f0b27 in 
 _D8ellipses13draw_ellipsesFPS3app6WindowPS3app8GraphicsZv ()
 #2  0x0804cbe7 in app_do_redraw_window ()
 #3  0x0804ceb5 in app_winproc ()
 #4  0x0804d226 in app_wait_event ()
 #5  0x0804d151 in app_main_loop ()
 #6  0x080f0c6e in _Dmain ()
 #7  0x080f1167 in main ()
 (gdb) continue
 Continuing.

 Program terminated with signal SIGSEGV, Segmentation fault.

 Here is the corresponding code piece :

 int main(char[][] args)
 {
 App *app;
 Window *w;
 char*[] myargs;
 myargs.length = args.length;
 foreach(int n,char[] str;args) {
 myargs[n]=toString(str);
 }
 int argc = args.length;
 app = app_new_app(argc,myargs.ptr);
 w = app_new_window(app, rect(10,10,448,400), "Ellipses Test",
 STANDARD_WINDOW);
 app_on_window_redraw(w,cast(WindowDrawFunc)(&draw_ellipses);

 draw ellipses then calls app_set_line_width(). I think the problem is the 
 way
 I cast draw_ellipses.

Since the stack is in set_line_width I'd guess the problem was in what was passed to set_line_width. More code about how set_line_width is called would help.
May 18 2005
parent reply Oliver <Oliver_member pathlink.com> writes:
In article <d6gkje$i3i$1 digitaldaemon.com>, Ben Hinkle says...
 That helped ! Now a window is opened - and the program crashes 
 immediately.
 Analysis with gdb yields :
 (gdb) bt
 #0  0x0804d869 in app_set_line_width ()
 #1  0x080f0b27 in 
 _D8ellipses13draw_ellipsesFPS3app6WindowPS3app8GraphicsZv ()
 #2  0x0804cbe7 in app_do_redraw_window ()
 #3  0x0804ceb5 in app_winproc ()
 #4  0x0804d226 in app_wait_event ()
 #5  0x0804d151 in app_main_loop ()
 #6  0x080f0c6e in _Dmain ()
 #7  0x080f1167 in main ()
 (gdb) continue
 Continuing.

 Program terminated with signal SIGSEGV, Segmentation fault.

 Here is the corresponding code piece :

 int main(char[][] args)
 {
 App *app;
 Window *w;
 char*[] myargs;
 myargs.length = args.length;
 foreach(int n,char[] str;args) {
 myargs[n]=toString(str);
 }
 int argc = args.length;
 app = app_new_app(argc,myargs.ptr);
 w = app_new_window(app, rect(10,10,448,400), "Ellipses Test",
 STANDARD_WINDOW);
 app_on_window_redraw(w,cast(WindowDrawFunc)(&draw_ellipses);

 draw ellipses then calls app_set_line_width(). I think the problem is the 
 way
 I cast draw_ellipses.

Since the stack is in set_line_width I'd guess the problem was in what was passed to set_line_width. More code about how set_line_width is called would help.

set_line_width is called in draw_ellipses : ============================================================================== void draw_ellipses(Window *w, Graphics *g) { int h, t, i; Rect r; r = rect(1,1,1,1); for (h=1; h <= 25; h++) /* try several ellipse heights */ { r.height = h; for (t=1; t <= h/2+1; t++) /* line widths */ { app_set_line_width(g, t); ========================================================================== The graphics structure (parameter g) is defined in app.d as follows: ========================================================================== struct Graphics { GraphicsExtra * extra; /* platform-specific data */ Colour colour; /* current drawing colour */ int pixval; /* current colour index */ Font * font; /* current text font */ int line_width; /* current pixel line width */ int text_direction; /* current text direction */ int xor_mode; /* currently XOR drawing? */ App * app; /* if required */ Window * win; /* target window, or */ Bitmap * bmap; /* target bitmap, or */ Control * ctrl; /* target control, or */ Image * img; /* target image */ Rect area; /* target's drawable area */ Region * clip; /* clip drawing to region */ Point offset; /* (0,0) is actually here */ CopyRectFunc copy_rect; /* pointer to drawing func */ FillRectFunc fill_rect; /* pointer to drawing func */ DrawUTF8Func draw_utf8; /* pointer to drawing func */ DrawLineFunc draw_line; /* pointer to drawing func */ } ============================================================================= I havent changed draw_ellipses - its unmodified C-code that compiles. regards, Oliver
May 18 2005
parent reply John Reimer <brk_6502 yahoo.com> writes:
Oliver...

Sorry to cut in on this conversation, but do you have any D X11 
interface modules?

I'm looking at using X11 on a project and it sure would nice not to have 
to create things from scratch.

Thanks,

JJR
May 18 2005
next sibling parent reply "Ben Hinkle" <ben.hinkle gmail.com> writes:
"John Reimer" <brk_6502 yahoo.com> wrote in message 
news:d6goiu$l1l$1 digitaldaemon.com...
 Oliver...

 Sorry to cut in on this conversation, but do you have any D X11 interface 
 modules?

 I'm looking at using X11 on a project and it sure would nice not to have 
 to create things from scratch.

 Thanks,

 JJR

in minwin I have been slowly porting by hand X11 and Motif headers (in the files x11.d and motif.d) http://home.comcast.net/~benhinkle/minwin/ I'm sure there's still many holes but it has enough to get minwin running on motif so it has the basics.
May 18 2005
parent John Reimer <brk_6502 yahoo.com> writes:
Ben Hinkle wrote:
 
 
 in minwin I have been slowly porting by hand X11 and Motif headers (in the 
 files x11.d and motif.d)
 http://home.comcast.net/~benhinkle/minwin/
 I'm sure there's still many holes but it has enough to get minwin running on 
 motif so it has the basics. 
 
 

Thanks, Ben... That's probably all I need too. I'll just add to it as I need stuff. - JJR
May 18 2005
prev sibling parent Oliver <Oliver_member pathlink.com> writes:
In article <d6goiu$l1l$1 digitaldaemon.com>, John Reimer says...
Oliver...

Sorry to cut in on this conversation, but do you have any D X11 
interface modules?

I'm looking at using X11 on a project and it sure would nice not to have 
to create things from scratch.

Thanks,

JJR

Hello ! What I am trying to do is using a GUI-libary called GraphApp with D. For this, I need to convert the header file(s) to D. The X11 lib is only used "indirectly" by the library. I cant provide u with such modules I am afraid, but luckily Ben seems to have sth. Have fun with D , Oliver
May 18 2005