今天在弄網頁的部分,網頁的內容有用到內嵌VLC,使用的Browser是IE
遇到一個很頭痛的問題是,當要從播放RTSP的VLC頁面中切換到別的頁面時,總是會造成IE Hang住,然後IE無回應 這時候IE只能強制關閉,然後重開。
猜想是因為離開頁面時,應該要呼叫VLC的Stop function先停止,再進行切換的動作。
先說明我網頁的架構如下圖所示,整個網頁有作分割式窗,上面小視窗的連結(herf)點擊之後,會在下面的main_Frame切換到超連結的頁面。另外每個Herf的區塊都有作自己要處理的onclick() function。
後來我查了一些資料得知,當頁面要離開到別的頁面時,javascript的部分會去作windows.onunload() 函式,因此我就把這個VLC的Stop function加入在這個onunload()當中。但後來發現情況並沒有改善。
在查詢了一些資料後,又有一個重大發現,原來onclick()、onunload()、herf這三個東西是有一個優先順序的,動作的先後順序為 onclick() => onunload() => herf
因此我把VLC的Stop function加入到架構圖中的上面三個的onclick事件要做的function當中,就解決了這個IE瀏覽器當VLC播放rtsp串流時切換頁面無回應的問題。
下面程式碼為javascript,附上javascript在mainFrame以及topFrame分別要呼叫VLC stop的程式碼:
=============== mainFrame 的 javascript部分 ==============
function getVLC(name)
{
if (window.document[name])
{
return window.document[name];
}
if (navigator.appName.indexOf("Microsoft Internet")==-1)
{
if (document.embeds && document.embeds[name])
return document.embeds[name];
}
else
{
return document.getElementById(name);
}
}
getVLC("vlc").playlist.stop();
=============== topFrame 的 javascript部分 ==============
function getVLC(name)
{
if (self.parent.frames["mainFrame"].document[name])
{
return self.parent.frames["mainFrame"].document[name];
}
if (navigator.appName.indexOf("Microsoft Internet")==-1)
{
if (self.parent.frames["mainFrame"].embeds && self.parent.frames["mainFrame"].document.embeds[name])
return self.parent.frames["mainFrame"].document.embeds[name];
}
else
{
return self.parent.frames["mainFrame"].document.getElementById(name);
}
}
getVLC("vlc").playlist.stop();
2015年7月29日 星期三
2015年7月21日 星期二
cross compiler openssl遇到的 target already defined - linux-elf (offending arg: CC=arm-linux-gcc) 問題~
今天在研究openssl,準備針對抓下來的opensource作cross compiler。
openssl的下載點(OPENSSL),我抓的版本為openssl-1.0.2a。
首先解開壓縮包之後,先作configure的動作,指令如下:
#./config CC=arm-linux-gcc
但不知道為什麼,一直出現下面的訊息,導致config無法完成
==> target already defined - linux-elf (offending arg: CC=arm-linux-gcc)
後來把指令改了一下,可以運作的指令如下:
#CC=arm-linux-gcc ./config no-asm shared
成功編譯完成的openssl執行檔會在 apps資料夾中
openssl的下載點(OPENSSL),我抓的版本為openssl-1.0.2a。
首先解開壓縮包之後,先作configure的動作,指令如下:
#./config CC=arm-linux-gcc
但不知道為什麼,一直出現下面的訊息,導致config無法完成
==> target already defined - linux-elf (offending arg: CC=arm-linux-gcc)
後來把指令改了一下,可以運作的指令如下:
#CC=arm-linux-gcc ./config no-asm shared
成功編譯完成的openssl執行檔會在 apps資料夾中
2015年7月1日 星期三
可變參數的function實作
由於最近寫的程式常常需要用到strcat ,而且一次要把好多個值strcat在一起
因此對可變參數的函式作了小小的研究,並寫成function以便日後使用
================== 正題開始 =================
在C/C++中,有所謂的variant argument(變動引數)。也就是可以讓函數
使用數量不固定的引數。printf()就是這類的函數。
定義一個函數的prototype(原型)時,若是將參數列以"..."代入,就表示這個函數即將
使用variant argument。如:
danny_func(char *result, ...)
這樣子便可讓編繹器不檢驗傳入這種函數裡的引數型態和數量,編出來的程式碼在呼叫端
就能夠盡可能地把各式各樣引數傳入。
那麼,在如此的程式裡,要怎麼存取variant argument呢?因為缺少引數變數,所以我們
不可能像一般程式一樣直接存取它們,而是要改用stdarg.h裡面所提供的三個巨集與一個
型別,分別是:
va_list: 宣告一個指標,讓它指向引數串列。
va_start: 初始化這個指標,讓它真正指向正確的引數串列開頭。
va_arg: 來取得va_list中的資料。
va_end: 清除這個指標,把它設為NULL。範例如下:
因此打算實作一個 danny_strcat(char *result, ...) 這樣子的function。
首先還是必須先使用到上面介紹的 linux當中的這些函式。
實作範例如下:
================= danny_strcat.c ====================
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
void danny_strcat(char *result, ...)
{
va_list ap;
char *p;
va_start(ap, result);
p = va_arg(ap, char *);
while (p != NULL) {
strcat(result, p);
p = va_arg(ap, char*);
}
va_end(ap);
}
int main(void)
{
char tmp[512]={0};
char tmp2[32]="strcat";
danny_strcat(tmp, "hello-", "world-", "danny-", tmp2, NULL);
printf("In main tmp=%s\n",tmp);
return 0;
}
輸出結果:
因此對可變參數的函式作了小小的研究,並寫成function以便日後使用
================== 正題開始 =================
在C/C++中,有所謂的variant argument(變動引數)。也就是可以讓函數
使用數量不固定的引數。printf()就是這類的函數。
定義一個函數的prototype(原型)時,若是將參數列以"..."代入,就表示這個函數即將
使用variant argument。如:
danny_func(char *result, ...)
這樣子便可讓編繹器不檢驗傳入這種函數裡的引數型態和數量,編出來的程式碼在呼叫端
就能夠盡可能地把各式各樣引數傳入。
那麼,在如此的程式裡,要怎麼存取variant argument呢?因為缺少引數變數,所以我們
不可能像一般程式一樣直接存取它們,而是要改用stdarg.h裡面所提供的三個巨集與一個
型別,分別是:
va_list: 宣告一個指標,讓它指向引數串列。
va_start: 初始化這個指標,讓它真正指向正確的引數串列開頭。
va_arg: 來取得va_list中的資料。
va_end: 清除這個指標,把它設為NULL。範例如下:
因此打算實作一個 danny_strcat(char *result, ...) 這樣子的function。
首先還是必須先使用到上面介紹的 linux當中的這些函式。
實作範例如下:
================= danny_strcat.c ====================
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
void danny_strcat(char *result, ...)
{
va_list ap;
char *p;
va_start(ap, result);
p = va_arg(ap, char *);
while (p != NULL) {
strcat(result, p);
p = va_arg(ap, char*);
}
va_end(ap);
}
int main(void)
{
char tmp[512]={0};
char tmp2[32]="strcat";
danny_strcat(tmp, "hello-", "world-", "danny-", tmp2, NULL);
printf("In main tmp=%s\n",tmp);
return 0;
}
輸出結果:
*目前的作法- 當呼叫這個可變參數的函式時,使用者必須在參數的最後面加上NULL,來告知它結束的點。
2015年6月13日 星期六
String轉unsigned long/String轉int/String轉float
有時候會需要用到一些型態轉換的C function因此這邊寫個小範例作個記錄~
=============== test_transit.c =================
#include <stdio.h>
int main()
{
unsigned long ul;
char str1[]="A5";
//strtoul第一個參數帶入要轉換的自串
//strtoul第三個參數帶入"要取幾進位的數"
ul = strtoul(str1, NULL, 16); // string to unsigned long
printf("==== String to unsigned long value(Hex)=%lX ====\n", ul);
printf("==== String to unsigned long value(D)=%ld ====\n", ul);
char str2[]="123";
int a = atoi(str2);
printf ("==== String to integer value=%d ====\n",a+10);
char str3[]="100.23";
float b = atof(str3);
printf ("==== String to float value=%f ====\n",b);
return 0;
=============== test_transit.c =================
#include <stdio.h>
int main()
{
unsigned long ul;
char str1[]="A5";
//strtoul第一個參數帶入要轉換的自串
//strtoul第三個參數帶入"要取幾進位的數"
ul = strtoul(str1, NULL, 16); // string to unsigned long
printf("==== String to unsigned long value(Hex)=%lX ====\n", ul);
printf("==== String to unsigned long value(D)=%ld ====\n", ul);
char str2[]="123";
int a = atoi(str2);
printf ("==== String to integer value=%d ====\n",a+10);
char str3[]="100.23";
float b = atof(str3);
printf ("==== String to float value=%f ====\n",b);
return 0;
}
===================================================
其中String轉unsigned long是成功的(OK)
String轉int也是成功的(OK)
但String轉float的部分有點問題,印出來的值跟轉換的字串不相同,這部分還需研究(Fail!) @@"
如果有研究出結果會在上來把float的部分更新
輸出結果:
2015年5月25日 星期一
判斷特定字串, 並改寫檔案的範例~
原本想要作到開啟一個設定檔,接著根據特定字串來直接改寫檔案
查詢了幾篇文章發現似乎無法這樣作
其中有個最主要的因素是因為:
文字檔是循序存放的,如果確定新資料與舊資料文字長度是一樣的,才可以直接作開檔、讀檔、再改寫。
舉個例子:
現在有一個設定檔login.info內容如下
username=danny
password=5566
location=taiwan
現在你想要讀出當字串為password時去改寫密碼的動作,假設你要新寫入的密碼為"123456",然後你使用直接開檔、讀檔、再改寫的方法,想必會變成下面的情形
username=danny
password=123456cation=taiwan
因為你新輸入的文字長度比舊的來的大,所以他會覆蓋到原本舊的其他的資料
=======================================================================
因此看來要改寫檔案就得用另一種方法了,這邊介紹的是,讀取原本檔案,然後寫入到另一個檔案去,沒有改寫的地方就照原本資料寫入,改寫的也一併寫入到新的資料。
最後再把原本資料砍掉,然後把新的資料改名成舊的資料名子。
詳細的範例如下所示:
首先是原始設定檔===========
devicename:dannyDevice
protocol:Bloger
resolution:HD
framerate:30
主要的程式碼部分============
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdarg.h>
#include <ctype.h>
#define DEVICE_INFO_PATH "./device.info"
#define TMP_DEVICE_INFO_PATH "./tmp_device.info"
最後的device.info檔案內容=======
devicename:dannyDevice
protocol:123
resolution:456
framerate:789
查詢了幾篇文章發現似乎無法這樣作
其中有個最主要的因素是因為:
文字檔是循序存放的,如果確定新資料與舊資料文字長度是一樣的,才可以直接作開檔、讀檔、再改寫。
舉個例子:
現在有一個設定檔login.info內容如下
username=danny
password=5566
location=taiwan
現在你想要讀出當字串為password時去改寫密碼的動作,假設你要新寫入的密碼為"123456",然後你使用直接開檔、讀檔、再改寫的方法,想必會變成下面的情形
username=danny
password=123456cation=taiwan
因為你新輸入的文字長度比舊的來的大,所以他會覆蓋到原本舊的其他的資料
=======================================================================
因此看來要改寫檔案就得用另一種方法了,這邊介紹的是,讀取原本檔案,然後寫入到另一個檔案去,沒有改寫的地方就照原本資料寫入,改寫的也一併寫入到新的資料。
最後再把原本資料砍掉,然後把新的資料改名成舊的資料名子。
詳細的範例如下所示:
首先是原始設定檔===========
devicename:dannyDevice
protocol:Bloger
resolution:HD
framerate:30
主要的程式碼部分============
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdarg.h>
#include <ctype.h>
#define DEVICE_INFO_PATH "./device.info"
#define TMP_DEVICE_INFO_PATH "./tmp_device.info"
void modify_file_func()
{
char buffer[128];
/* open login info in device. */
FILE *fptr, *fptr_tmp;
char tmp[64]={0};
if ((fptr = fopen(DEVICE_INFO_PATH, "r")) == NULL)
{
printf("open_file_error");
exit(1);
}
else if((fptr_tmp = fopen(TMP_DEVICE_INFO_PATH, "w")) == NULL)
{
printf("open_tmp_file_error");
exit(1);
}
while(fgets(buffer, sizeof(buffer), fptr) != NULL)
{
if(strstr(buffer, "protocol:"))
{
sprintf(tmp,"protocol:%s\n", 123);
fputs(tmp, fptr_tmp);
memset(tmp,'\0',sizeof(tmp));
}
else if(strstr(buffer, "resolution:"))
{
sprintf(tmp,"resolution:%s\n", 456);
fputs(tmp, fptr_tmp);
memset(tmp,'\0',sizeof(tmp));
}
else if(strstr(buffer, "framerate:"))
{
sprintf(tmp,"framerate:%s\n", 789);
fputs(tmp, fptr_tmp);
memset(tmp,'\0',sizeof(tmp));
}
else
fputs(buffer, fptr_tmp);
}
fclose(fptr);
fclose(fptr_tmp);
//刪掉原檔案,並改寫新檔案的名子
sprintf(tmp,"rm %s;mv %s %s", DEVICE_INFO_PATH, TMP_DEVICE_INFO_PATH, DEVICE_INFO_PATH);
system(tmp);
}
int main()
{
modify_file_func();
return 0;
}
最後的device.info檔案內容=======
devicename:dannyDevice
protocol:123
resolution:456
framerate:789
2015年5月21日 星期四
shell script中判斷命令是否正確成功的作法
首先先稍微了解一下 "1>/dev/null 2>&1"
0 = standard input (stdin)
1 = standard output (stdout)
2 = standard error (stderr)
"1>/dev/null 2>&1" 首先stdout的標準輸出的訊息會先丟到/dev/null,接著stderr的訊息也一起丟到stdout也就是丟到/dev/null,所以訊息不會顯示在螢幕上。
而/dev/null,是空裝置,是一個特殊的裝置檔案,它會丟棄一切寫入其中的資料。
======================================================================
下面我們寫一個簡單的範例來練習, 用一個正確的command($ok_cmd)以及故意寫一個錯誤的command($error_cmd),指令成功會回傳1,錯誤則回傳0,執行並判斷command是否正確。
程式碼如下:
#!/bin/sh
ok_cmd='ls -al'
error_cmd='ls --al'
if $ok_cmd 1>/dev/null 2>&1; then
echo "ok_cmd is OK!."
else
echo "ok_cmd is ERROR!."
fi
if $error_cmd 1>/dev/null 2>&1; then
echo "error_cmd is OK!."
else
echo "error_cmd is ERROR!."
fi
0 = standard input (stdin)
1 = standard output (stdout)
2 = standard error (stderr)
"1>/dev/null 2>&1" 首先stdout的標準輸出的訊息會先丟到/dev/null,接著stderr的訊息也一起丟到stdout也就是丟到/dev/null,所以訊息不會顯示在螢幕上。
而/dev/null,是空裝置,是一個特殊的裝置檔案,它會丟棄一切寫入其中的資料。
======================================================================
下面我們寫一個簡單的範例來練習, 用一個正確的command($ok_cmd)以及故意寫一個錯誤的command($error_cmd),指令成功會回傳1,錯誤則回傳0,執行並判斷command是否正確。
程式碼如下:
#!/bin/sh
ok_cmd='ls -al'
error_cmd='ls --al'
if $ok_cmd 1>/dev/null 2>&1; then
echo "ok_cmd is OK!."
else
echo "ok_cmd is ERROR!."
fi
if $error_cmd 1>/dev/null 2>&1; then
echo "error_cmd is OK!."
else
echo "error_cmd is ERROR!."
fi
結果輸出:
2015年5月6日 星期三
當apt_get_update時遇到問題時的解決方法 ERROR MSG:(Problem with MergeList)(status file could not be parsed or opened)
之前要作 apt-get update,當更新到最後時出現了下面的Error message:
======================================================================
當遇到上面的錯誤情形時,只需要作以下幾個步驟就可以解決了:
首先叫出Terminal接著輸入以下幾個指令
1. sudo rm /var/lib/apt/lists/* -vf
2. sudo apt-get update
註:執行上面兩個指令之前,可以先將 /var/lib/apt/list/ 底下的東西全部備份,以免作了上面兩個步驟之後還是無法解決的話,可以復原 :D
E: Encountered a section with no Package: header
E: Problem with MergeList /var/lib/apt/lists/archive.ubuntu.com_ubuntu_dists_natty_main_binary-i386_Packages
E: The package lists or status file could not be parsed or opened.
======================================================================
當遇到上面的錯誤情形時,只需要作以下幾個步驟就可以解決了:
首先叫出Terminal接著輸入以下幾個指令
1. sudo rm /var/lib/apt/lists/* -vf
2. sudo apt-get update
註:執行上面兩個指令之前,可以先將 /var/lib/apt/list/ 底下的東西全部備份,以免作了上面兩個步驟之後還是無法解決的話,可以復原 :D
訂閱:
文章 (Atom)