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.
420splash_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 intWPARAM;
typedef unsigned long LPARAM;
发现在64位上,长度不一样。
typedef unsigned longWPARAM;
typedef unsigned long LPARAM;
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7a10167 in OnChangeSize (pWin=0x609dd0, pDestRect=0x609dd4,
pResultRect=0x0) at window.c:1733
1733info->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 <error: Cannot access memory at address 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
4668MG_CHECK_RET (MG_IS_NORMAL_WINDOW(hWnd), HDC_INVALID);
(gdb) n
4669pWin = MG_GET_WINDOW_PTR (hWnd);
(gdb) n
4672if (pWin->pCaretInfo && pWin->pCaretInfo->fBlink) {
(gdb) n
4677hdc = get_valid_dc (pWin, TRUE);
(gdb)
4685pInvRgn = &pWin->InvRgn;
(gdb)
4688pthread_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' <repeats 39 times>, __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 <sg_FreeInvRectList>},
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 <DCSlot+968>)
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 <DCSlot+968>) at gdi.c:1658
#1 0x00007ffff7ad1530 in _dc_set_pixel_noclip (
context=0x7ffff7dd5868 <DCSlot+584>, stepx=1, stepy=-1) at pixel_ops.c:165
#2 0x00007ffff7ad56f4 in LineGenerator (context=0x7ffff7dd5868 <DCSlot+584>,
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????", <incomplete sequence \326>
(gdb) n
_dc_set_pixel_noclip (context=0x7ffff7dd5868 <DCSlot+584>, stepx=1, stepy=-1)
at pixel_ops.c:163
163if (stepy) _dc_step_y (pdc, stepy);
(gdb) s
_dc_step_y (pdc=0x7ffff7dd5868 <DCSlot+584>, step=-1)
at /home/learningx/minigui/libminigui-gpl-3.0.12/src/include/dc.h:445
445pdc->cur_dst += pdc->surface->pitch * step;
(gdb) p pdc->cur_dst
$21 = (gal_uint8 *) 0x7ffff7ecf568 "\231????", <incomplete sequence \326>
(gdb) n
446 }
(gdb) p pdc->cur_dst
$22 = (gal_uint8 *) 0x8000f7ecef28 <error: Cannot access memory at address 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
365info->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 <gmTextBufferClass>,
addData=addData@entry=0) at object.c:91
#3 0x00007ffff7a8caa3 in mTextEditor_construct (self=0x609bd0,
addData=<optimized out>) at mtextedit.c:3947
#4 0x00007ffff7a897a0 in mgNewObject (
_class=_class@entry=0x7ffff7db1000 <gmTextEditorClass>,
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=<optimized out>,
str=0x7ffff6beb801 "free(): invalid pointer", action=1) at malloc.c:4996
#4 _int_free (av=<optimized out>, p=<optimized out>, 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=<optimized out>,
wParam=1024, lParam=<optimized out>) 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