minigui成功移植到ubuntu64位平台

1.pc系统ubuntu14LTS 64bit,同时在32位ubuntu16.04上经过了测试,官方的所有范例程序都能运行。

2.过两天会写份详细的移植教程,现在只是将移植好的文件上传到我的csdn下载,大家可以免费下载。

3.做个简单的移植过程说明:为了和32位兼容,后面做了一些改动,完全照做可能需要你动动脑筋,呵呵

编译时要注意:
第一:./configure --enable-pngsupport --enable-jpegsupport
第二:Makefile文件中加链接参数 -lpng -ljpeg

当然还有一些小问题,就不说了,如果还有疑问欢迎一起QQ交流:848416881

附上百度云盘下载地址: https://pan.baidu.com/s/1mhEGGvY

核心库编译错误:

Q1:object.h: In function 'MGGET_ARG_COUNT':
object.h:275: error: incompatible types when assigning to type 'va_list' from type 'struct __va_list_tag *'

分析:
va 作为函数参数的时候会转换成指针类型,而_va.va是数组类型   所以报类型不匹配错误。谷歌下就能解决
解决:
// _va.va = va;
va_copy(_va.va, va);

Q2;
/usr/bin/ld: CMakeFiles/gvfb.dir/gvfb_linux.o: undefined reference to symbol 'XkbGetIndicatorState'
//usr/lib/x86

gvfb/src/CMakeFiles/gvfb.dir目录下有一个link.txt文件
-lX11 -L/usr/lib/x86_64-linux-gnu/libXtst.a  -L/usr/lib/x86_64-linux-gnu/libX11.a

Q3:
start-qvfb :/usr/local/bin/gvfb pcxvfb 29490
XVFB-for-MiniGUI-3.0-(Gtk-Version) 800×600-16bpp Aborted (core dumped)

将HDC定义改为 typedef unsigned long HDC;  64位要用unsigned long表示指针。

Q4:
KERNEL>InitGUI: Count not init mouse cursor!
KERNEL>InitGUI: Init failure, please check your MiniGUI configuration or resource.

解决:
Uint16 MGUI_ReadLE16FP (FILE *src)
{
Uint16 value;

fread (&value, (sizeof value), 1, src);
return(ArchSwapLE16(value));
}
在src/misc/endianrw.c中该函数处添加大小端判断代码。其实LE就是表示该函数是用来处理小端数据的。先这样吧,后面还会有这个问题
反正知道是大小端问题

int checkSystem(void)
{
    union check
    {
        int i;
        char ch;
    }c;
    c.i = 1;
    return (c.ch==1);
}

Uint16 MGUI_ReadLE16FP (FILE *src)
{
        Uint16 value;


        fread (&value, (sizeof value), 1, src);
        if(1==checkSystem())
             return value;
        else
             return(ArchSwapLE16(value));
}

同时发现解析位图的时候,有误。DWORD在32bit cpu中是32位  而64位机器中是64位
#ifndef _HAVE_TYPE_DWORD
typedef unsigned long   DWORD;
#endif

将cursor.c文件中的位图加载函数LoadCursorFromFile中的DWORD改成4。位图如何解析百度上有很详细的介绍。

Q:5
get_image_type: unknown type png.
get_image_type: unknown type png.
get_image_type: unknown type png.
get_image_type: unknown type png.
get_image_type: unknown type png.
420    splash_draw_framework(); 

跟踪代码发现,这里应该要显示飞漫的启动动画的。 配置png支持的宏没有打开,最好先编译安装飞漫官方的png库, _MGIMAGE_PNG, 重新编译核心库gpl,
./configure --enable-pngsupport  这里其实jpeg库也没支持,先不管,用到再说,这时候编译same会出错,因为Makefile中
没有添加png的链接,Makefile中添加  LIBS += -lpng
这时候重新编译核心库,gvfb库和same程序,gdb调试发现飞漫启动画面运行了。

KERNEL>InitGUI: Initialization of LF Manager failure!

MGUI_ReadLE16、MGUI_ReadLE32(MGUI_ReadLE16FP)函数没进行大小端判断,添加判断即可,也就是小端直接返回value。

紧接着  在发生段错误
PGCRINFO kernel_GetGCRgnInfo (HWND hWnd)
{
    return ((PMAINWIN)hWnd)->pGCRInfo;
},
我们是64位机器,当然不行。
typedef unsigned long HWND;

段错误
PGCRINFO kernel_GetGCRgnInfo (HWND hWnd)
{
    return ((PMAINWIN)hWnd)->pGCRInfo;
},
我们是64位机器,当然不行。
typedef unsigned long HWND;

Program received signal SIGSEGV, Segmentation fault.
__memcpy_sse2_unaligned ()
    at ../sysdeps/x86_64/multiarch/memcpy-sse2-unaligned.S:157
157 ../sysdeps/x86_64/multiarch/memcpy-sse2-unaligned.S: No such file or directory.

(gdb) bt
#0  __memcpy_sse2_unaligned ()
    at ../sysdeps/x86_64/multiarch/memcpy-sse2-unaligned.S:157
#1  0x00007ffff7a106aa in DefaultPostMsgHandler (pWin=0x609dd0, message=37, 
    wParam=4294958728, lParam=6331860) at window.c:1997
#2  0x00007ffff7a11404 in PreDefMainWinProc (hWnd=6331856, message=37, 
    wParam=4294958728, lParam=6331860) at window.c:2428
#3  0x0000000000403078 in SameGameProc (hWnd=6331856, message=37, 
    wParam=4294958728, lParam=6331860) at same.c:666
#4  0x00007ffff7a4adb9 in SendMessage (hWnd=6331856, iMsg=37, 
    wParam=4294958728, lParam=6331860) at message.c:875
#5  0x00007ffff7a13527 in CreateMainWindowEx (pCreateInfo=0x7fffffffde50, 
    werdr_name=0x0, we_attrs=0x0, window_name=0x0, layer_name=0x0)
    at window.c:3496
#6  0x000000000040176d in CreateMainWindow (pCreateInfo=0x7fffffffde50)
    at /usr/local/include/minigui/window.h:5039
#7  0x0000000000403247 in MiniGUIAppMain (argc=1, argv=0x7fffffffdfc8)
    at same.c:722
#8  0x0000000000403205 in main (args=1, argv=0x7fffffffdfc8) at same.c:697


        case MSG_SIZECHANGING:
            memcpy ((PRECT)lParam, (PRECT)wParam, sizeof (RECT));
            break;

看看 WPARAM wParam, LPARAM lParam这两个参数,
typedef unsigned int    WPARAM;
typedef unsigned long   LPARAM;
发现在64位上,长度不一样。
typedef unsigned long    WPARAM;
typedef unsigned long   LPARAM;

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7a10167 in OnChangeSize (pWin=0x609dd0, pDestRect=0x609dd4, 
    pResultRect=0x0) at window.c:1733
1733            info->we_rdr->calc_we_metrics ((HWND)pWin, NULL, 
(gdb) bt
#0  0x00007ffff7a10167 in OnChangeSize (pWin=0x609dd0, pDestRect=0x609dd4, 
    pResultRect=0x0) at window.c:1733
#1  0x00007ffff7a109b9 in DefaultPostMsgHandler (pWin=0x609dd0, message=34, 
    wParam=6331860, lParam=0) at window.c:1992
#2  0x00007ffff7a11755 in PreDefMainWinProc (hWnd=6331856, message=34, 
    wParam=6331860, lParam=0) at window.c:2428
#3  0x000000000040308c in SameGameProc (hWnd=6331856, message=34, 
    wParam=6331860, lParam=0) at same.c:666
#4  0x00007ffff7a4b1f9 in SendMessage (hWnd=6331856, iMsg=34, wParam=6331860, 
    lParam=0) at message.c:875
#5  0x00007ffff7a13899 in CreateMainWindowEx (pCreateInfo=0x7fffffffde50, 
    werdr_name=0x0, we_attrs=0x0, window_name=0x0, layer_name=0x0)
    at window.c:3498
#6  0x000000000040176d in CreateMainWindow (pCreateInfo=0x7fffffffde50)
    at /usr/local/include/minigui/window.h:5039
#7  0x000000000040325b in MiniGUIAppMain (argc=1, argv=0x7fffffffdfc8)
    at same.c:722
#8  0x0000000000403219 in main (args=1, argv=0x7fffffffdfc8) at same.c:697

include/window.h
static inline const WINDOWINFO* GUIAPI GetWindowInfo (HWND hWnd)
{
    return (WINDOWINFO*)((unsigned char*)hWnd + 2*sizeof (short));//???
}

// this struct is an internal struct
typedef struct _MAINWIN
{
    /*
     * These fields are similiar with CONTROL struct.
     */
    unsigned char DataType;     // the data type.
    unsigned char WinType;      // the window type.
unsigned short Flags;       // special runtime flags, such EraseBkGnd flags

(gdb) p *info
$1 = {left = 0, top = 0, right = 610, bottom = 475, cl = 0, ct = 0, cr = 0, 
  cb = 0, dwStyle = 2323857407723175936, dwExStyle = 0, iBkColor = 0, 
  hMenu = 27161407539642368, hAccel = 0, hCursor = 0, hIcon = 6361040, 
  hSysMenu = 0, pLogFont = 0x60a68000000000, 
  spCaption = 0xf7fd302800000000 , id = 32767, vscroll = {minPos = 0, maxPos = 0, curPos = 0, 
    pageStep = 0, arrowLen = 0, barStart = 0, barLen = 0, status = 0}, 
  hscroll = {minPos = 3, maxPos = 0, curPos = 0, pageStep = 0, arrowLen = 0, 
    barStart = 0, barLen = 0, status = 0}, we_rdr = 0xf7da75a000000000}
解决:字节对齐问题,发现dwStyle 开始地址就不对,info地址算错了(是说64位平台不对)

问题根源是32位平台gcc结构体默认是4字节对齐,而64位平台是8字节对齐,所以导致地址差了4字节,所以算偏移量时候要注意。我再前三个变量后面填充了一个int型

变量fills(为了不引起误会,让大家注意到字节对齐问题)
static inline const WINDOWINFO* GUIAPI GetWindowInfo (HWND hWnd)
{
    return (WINDOWINFO*)((unsigned char*)hWnd + sizeof(long));
}

BeginPaint (hWnd=6323664) at window.c:4668
4668    MG_CHECK_RET (MG_IS_NORMAL_WINDOW(hWnd), HDC_INVALID);
(gdb) n
4669    pWin = MG_GET_WINDOW_PTR (hWnd);
(gdb) n
4672    if (pWin->pCaretInfo && pWin->pCaretInfo->fBlink) {
(gdb) n
4677    hdc = get_valid_dc (pWin, TRUE);
(gdb) 
4685    pInvRgn = &pWin->InvRgn;
(gdb) 
4688    pthread_mutex_lock (&pInvRgn->lock);
(gdb) p pInvRgn
$1 = (PINVRGN) 0x607e98
(gdb) p *pInvRgn
$2 = {lock = {__data = {__lock = 0, __count = 0, __owner = 0, __nusers = 0, 
      __kind = 0, __spins = 0, __elision = 0, __list = {__prev = 0x0, 
        __next = 0x0}}, __size = '\000' , __align = 0}, 
  rgn = {type = 1 '\001', reserved = "\000\000\000\000\000\000", rcBound = {
      left = 0, top = 0, right = -272, bottom = 480}, head = 0x7ffff000ad08, 
    tail = 0x7ffff000ad08, heap = 0x7ffff7dd49e0 }, 
  frozen = 0}

right = -272, bottom = 480    //right=480  bottom=272

解决:
typedef struct tagCONTROL
{
    /*
     * These fields are similiar with MAINWIN struct.
     */
    unsigned char DataType;         // the data type
    unsigned char WinType;          // the window type
unsigned short Flags;           // speical runtime flags, such EraseBkGnd flags


    int left, top;          // the position of control in main window's
    int right, bottom;      // client area.

    int cl, ct;             // the positio of control client in main window's
    int cr, cb;             // client area.
这个结构体开始3个变量忘了改成8字节对齐。也在第三个变量后面填充一个int型变量fills。

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7ffff61f2700 (LWP 11168)]
0x00007ffff7ab97ad in _dc_set_pixel_2 (comp_ctxt=0x7ffff7dd59e8 )
    at gdi.c:1658
1658    *(Uint16 *) comp_ctxt->cur_dst = (Uint16) comp_ctxt->cur_pixel;
(gdb) bt
#0  0x00007ffff7ab97ad in _dc_set_pixel_2 (
    comp_ctxt=0x7ffff7dd59e8 ) at gdi.c:1658
#1  0x00007ffff7ad1530 in _dc_set_pixel_noclip (
    context=0x7ffff7dd5868 , stepx=1, stepy=-1) at pixel_ops.c:165
#2  0x00007ffff7ad56f4 in LineGenerator (context=0x7ffff7dd5868
    x1=592, y1=17, x2=598, y2=11, cb=0x7ffff7ad14c5 <_dc_set_pixel_noclip>)
    at generators.c:333
#3  0x00007ffff7acf8ed in LineTo (hdc=140737351866472, x=598, y=11)
    at line.c:98
#4  0x00007ffff7a2122a in draw_caption_button (hWnd=6331856, 
    hdc=140737351866472, ht_code=0, status=0) at lf_classic.c:2512
#5  0x00007ffff7a10deb in wndDrawNCFrame (pWin=0x609dd0, hdc=140737351866472, 
    prcInvalid=0x0) at window.c:2143
#6  0x00007ffff7a11109 in DefaultPaintMsgHandler (pWin=0x609dd0, message=178, 
    wParam=0, lParam=0) at window.c:2216
#7  0x00007ffff7a117ae in PreDefMainWinProc (hWnd=6331856, message=178, 
    wParam=0, lParam=0) at window.c:2432
#8  0x000000000040308c in SameGameProc (hWnd=6331856, message=178, wParam=0, 
    lParam=0) at same.c:666
#9  0x00007ffff7a4bff2 in SendAsyncMessage (hWnd=6331856, iMsg=178, wParam=0, 
    lParam=0) at message.c:1349
#10 0x00007ffff7a441cc in dskMoveToTopMost (pWin=0x609dd0, reason=3, lParam=0)
    at desktop-comm.c:290

988 }
(gdb) p pdc->cur_dst 
$20 = (gal_uint8 *) 0x7ffff7ecf568 "\231????",
(gdb) n
_dc_set_pixel_noclip (context=0x7ffff7dd5868 , stepx=1, stepy=-1)
    at pixel_ops.c:163
163    if (stepy) _dc_step_y (pdc, stepy);
(gdb) s
_dc_step_y (pdc=0x7ffff7dd5868 , step=-1)
    at /home/learningx/minigui/libminigui-gpl-3.0.12/src/include/dc.h:445
445    pdc->cur_dst += pdc->surface->pitch * step;
(gdb) p pdc->cur_dst 
$21 = (gal_uint8 *) 0x7ffff7ecf568 "\231????",
(gdb) n
446 }
(gdb) p pdc->cur_dst 
$22 = (gal_uint8 *) 0x8000f7ecef28
(gdb) p pdc->surface->pitch
$23 = 1600
(gdb) p step
$24 = -1

问题在于这个函数:
static inline void _dc_step_y (PDC pdc, int step)
{
    pdc->cur_dst += pdc->surface->pitch * step;
}

0x7ffff7ecf568  + (-1600)的问题,根源在于64位平台左边是个64位的指针,右边却是32位,那么将右边的数据强转成64位计算。

将pitch和step强转数据类型:
static inline void _dc_step_y (PDC pdc, int step)
{
    pdc->cur_dst += (unsigned long)pdc->surface->pitch * (long)step;
}

Program received signal SIGBUS, Bus error.
0x00007ffff79f8be3 in load_font_data (
    fontname=0x407ce0 "vbf-Courier-rrncnn-8-13-ISO8859-1", 
    filename=0x407ca8 "/usr/local/share/minigui/res/font/Courier-rr-8-13.vbf")
    at varbitmap.c:365
365    info->max_width = propt->max_width;

大小端问题:
#if MGUI_BYTEORDER == MGUI_BIG_ENDIAN
    len_header = ArchSwap16 (len_header);
    swap_intdata ((Uint32*)&layout, sizeof(layout)/sizeof(int));
#endif
这句不该运行的,根源于:加定义__x86_64__
#if  defined(__i386__) || defined(__ia64__) || \
    (defined(__alpha__) || defined(__alpha)) || \
     defined(__arm__) || \
    (defined(__CC_ARM) && !defined(__BIG_ENDIAN)) || \
    (defined(__mips__) && defined(__MIPSEL__)) || \
     defined(__LITTLE_ENDIAN__) || \
    defined(WIN32)
#define MGUI_BYTEORDER   MGUI_LIL_ENDIAN
#else
#define MGUI_BYTEORDER   MGUI_BIG_ENDIAN
#endif

Program received signal SIGSEGV, Segmentation fault.
_minigui_ncsParseConstructParams (args=args@entry=0x0, 
    signature=signature@entry=0x7ffff7b48cdd "si") at object.c:210
210 if(GET_ARG_COUNT(args) <= 0)
(gdb) p args
$1 = (struct __va_list_tag *) 0x0
(gdb) bt
#0  _minigui_ncsParseConstructParams (args=args@entry=0x0, 
    signature=signature@entry=0x7ffff7b48cdd "si") at object.c:210
#1  0x00007ffff7a92488 in mTextBuffer_construct (self=0x608930, va=0x0)
    at mtextedit.c:168
#2  0x00007ffff7a897a0 in mgNewObject (
    _class=_class@entry=0x7ffff7db1500
    addData=addData@entry=0) at object.c:91
#3  0x00007ffff7a8caa3 in mTextEditor_construct (self=0x609bd0, 
    addData=) at mtextedit.c:3947
#4  0x00007ffff7a897a0 in mgNewObject (
    _class=_class@entry=0x7ffff7db1000
    addData=addData@entry=6330880) at object.c:91
#5  0x00007ffff7a8de7f in mTextEditCtrlProc (hWnd=

解决:根据自己的平台添加,具体要加什么谷歌吧
#if  defined (__x86_64__) || defined(__i386__) || defined(__ia64__) || \
    (defined(__alpha__) || defined(__alpha)) || \
     defined(__arm__) || \
    (defined(__CC_ARM) && !defined(__BIG_ENDIAN)) || \
    (defined(__mips__) && defined(__MIPSEL__)) || \
     defined(__LITTLE_ENDIAN__) || \
    defined(WIN32)

问题:
205 {
(gdb) n
210 if(GET_ARG_COUNT(args) <= 0)
(gdb) s
MGGET_ARG_COUNT (va=va@entry=0x0) at object.h:276
276 va_copy(_va.va, va);//这行有问题
(gdb) s

Program received signal SIGSEGV, Segmentation fault.
_minigui_ncsParseConstructParams (args=args@entry=0x0, 
    signature=signature@entry=0x7ffff7b48cdd "si") at object.c:210
210 if(GET_ARG_COUNT(args) <= 0)

static inline int MGGET_ARG_COUNT(va_list va)
{
union {
va_list va;
DWORD   dva;
}_va;
// _va.va = va;
va_copy(&_va.va, &va);

if(_va.dva == 0)
return 0;
//return va_arg(va, int); 
    //DON'T call va_arg, because, va_arg can change va's value
    //this is a inline function, in some compiler, the change would
    //be pass to its caller
    return 1;
}

#0  0x00007ffff6aa4c37 in __GI_raise (sig=sig@entry=6)
    at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
#1  0x00007ffff6aa8028 in __GI_abort () at abort.c:89
#2  0x00007ffff6ae12a4 in __libc_message (do_abort=do_abort@entry=1, 
    fmt=fmt@entry=0x7ffff6bef6b0 "*** Error in `%s': %s: 0x%s ***\n")
    at ../sysdeps/posix/libc_fatal.c:175
#3  0x00007ffff6aed55e in malloc_printerr (ptr=
    str=0x7ffff6beb801 "free(): invalid pointer", action=1) at malloc.c:4996
#4  _int_free (av=, p=, have_lock=0)
    at malloc.c:3840
#5  0x00007ffff7a55492 in MainWindowThreadCleanup (hMainWnd=6324688)
    at window.c:3269
#6  0x000000000040301a in app_watch (hosting=6331856, ue_type=0) at watch.c:435
#7  0x0000000000401542 in my_notif_proc (hwnd=6722416, id=1, nc=0, add_data=0)
    at dbuff.c:107
#8  0x00007ffff7a0f1a5 in change_status_from_pose (pctrl=pctrl@entry=0x669370, 
    new_pose=new_pose@entry=1, noti_pose_changing=noti_pose_changing@entry=1, 
    change_valid=change_valid@entry=1) at button.c:277
#9  0x00007ffff7a0fd46 in ButtonCtrlProc (hWnd=6722416, uMsg=
    wParam=1024, lParam=) at button.c:953
#10 0x00007ffff7a8641f in DispatchMessage (pMsg=0x7fffffffde00)
    at message.c:1061

void GUIAPI MainWindowThreadCleanup (HWND hMainWnd)
{
    PMAINWIN pWin = (PMAINWIN)hMainWnd;


    if (!MG_IS_DESTROYED_WINDOW (hMainWnd)) {
#ifdef _DEBUG
        fprintf (stderr, "GUI>Window: Unexpected calling of "
                "(MainWindowThreadCleanup); Window (%x) "
                "not destroyed yet!\n",
                hMainWnd);
#endif
        return;
    }

#ifdef _MGRM_THREADS
    if (pWin->pHosting == NULL) {
        mg_FreeMsgQueueThisThread ();
    }
#endif

解决:free前将DataType修改

    pWin->DataType = TYPE_UNDEFINED;
    free (pWin);//bug  

minigui成功移植到ubuntu64位平台_第1张图片


你可能感兴趣的:(嵌入式开发)