最近因工作需要研究了一下facebook的API调用.
虽然是一个不存在的网站,但也是工作内容的一部分,需要认真对待.既然对于咱们国人来说不存在,当然也就没有汉字可看了.英文文档让我头晕了好一阵子,吐了好几次之后终于摸清了脉络.
大致步骤是:
1、创建一个应用程序,可以获得App ID/API Key和App Secret。
2、使用URL:
其中YOUR_APP_ID就是你的APPID, YOUR_URL就是你应用程序的URL,Canvas程序就填Canvas的URI, scope就是请求的权限.
这个界面进去就是跟国内的微博应用一样了,是一个申请用户授权的页面,用户点击授权后,facebook会这样请求你的YOUR_URL:
http://your_url/?code=A_CODE_GENERATED_BY_SERVER
你的URL会收到一大串加密字符的Get请求.
3、拿出这一大串密钥,通过下面的URI获取到access_token
最后的code 就是第二步获取到的code了.请求这个URI会得到access_token,拿到这个之后,就可以在任何地方做你想做的事啦.
4、各种API:
- Friends: https://graph.facebook.com/me/friends?access_token=...
- News feed: https://graph.facebook.com/me/home?access_token=...
- Profile feed (Wall): https://graph.facebook.com/me/feed?access_token=...
- Likes: https://graph.facebook.com/me/likes?access_token=...
- Movies: https://graph.facebook.com/me/movies?access_token=...
- Music: https://graph.facebook.com/me/music?access_token=...
- Books: https://graph.facebook.com/me/books?access_token=...
- Notes: https://graph.facebook.com/me/notes?access_token=...
- Permissions: https://graph.facebook.com/me/permissions?access_token=...
- Photo Tags: https://graph.facebook.com/me/photos?access_token=...
- Photo Albums: https://graph.facebook.com/me/albums?access_token=...
- Video Tags: https://graph.facebook.com/me/videos?access_token=...
- Video Uploads: https://graph.facebook.com/me/videos/uploaded?access_token=...
- Events: https://graph.facebook.com/me/events?access_token=...
- Groups: https://graph.facebook.com/me/groups?access_token=...
- Checkins: https://graph.facebook.com/me/checkins?access_token=...
API手册:https://developers.facebook.com/docs/reference/api/
不知道该不该放首页,惶恐的放一下吧,或许有人要用到也说不准呢。
先看图

32位下正常

64位就乱码了.

然后我把结构体里面的_buffer_length去掉,就是结构体里面只有一个指针,这样又正常了.
x64的硬转指针有什么特殊规则?还是printf的x64版本的读取参数跟32位不太一样?
2011/10/25 1:16
测试了一下发现并不是指针硬转什么的问题.而是变长参数在x64编译环境下读取出来的地址不对.但还是没查出来具体原因.
调试了一整天,WSARecv一直不成功,GetLastError()返回错误代码6 也就是所谓的ERROR_INVALID_HANDLE,但断点调试一下发现SOCKET没错啊,很正常的一个数字.
上网一查发现是OVERLAPPED结构体需要用memset初始化一下,用memset日完之后果然就正常了.
留个笔记方便后人查看.哈哈.
参考资料:http://topic.csdn.net/u/20081205/20/1c614b49-6e19-47b9-b02d-ace67d9a01fe.html
搞了2个小时了,其实很简单,有两个函数Windows API官方说明上写着仅限Windows 16bit平台使用,但是为神马我虚拟机的32位XP可以用呢?
这个问题暂时想不通,不过总算是解决了.
只需要把OpenFile函数换成了CreateFile函数把_lread函数换成了ReadFile函数,把_lclose函数换成了CloseHandle函数,然后注释掉_lseek函数即可.
附上相关函数的官方帮助文档:
_lseek:http://msdn.microsoft.com/zh-cn/library/1yee101t(v=VS.80).aspx
_lread:找不到
_lclose:找不到.
CreateFile:http://msdn.microsoft.com/zh-cn/library/aa363858%28en-us,VS.85%29.aspx
ReadFile:http://msdn.microsoft.com/zh-cn/library/aa365467.aspx
CloseHandle:http://msdn.microsoft.com/en-us/library/ms724211(v=VS.85).aspx
书上P279,Load_Bitmap_File函数
int Load_Bitmap_File(BITMAP_FILE_PTR bitmap, char *filename)
{
// this function opens a bitmap file and loads the data into bitmap
HANDLE file_handle; // the file handle
int index; // looping index
UCHAR *temp_buffer = NULL; // used to convert 24 bit images to 16 bit
OFSTRUCT file_data; // the file data information
// open the file if it exists
//if ((file_handle = OpenFile(filename,&file_data,OF_READ))==-1)
// return(0);
if ((file_handle = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) == NULL) //注意这里,把OpenFile函数换成了CreateFile函数
return(0);
// now load the bitmap file header
//_lread(file_handle, &bitmap->bitmapfileheader,sizeof(BITMAPFILEHEADER));
DWORD numberOfBytesRead;
ReadFile(file_handle, &bitmap->bitmapfileheader, sizeof(BITMAPFILEHEADER),&numberOfBytesRead,NULL); //注意这里,把_lread函数换成了ReadFile函数
// test if this is a bitmap file
if (bitmap->bitmapfileheader.bfType!=BITMAP_ID)
{
// close the file
//_lclose(file_handle);
CloseHandle(file_handle); //注意这里把_lclose函数换成了CloseHandle函数
// return error
return(0);
} // end if
// now we know this is a bitmap, so read in all the sections
// first the bitmap infoheader
// now load the bitmap file header
//_lread(file_handle, &bitmap->bitmapinfoheader,sizeof(BITMAPINFOHEADER));
ReadFile(file_handle,&bitmap->bitmapinfoheader,sizeof(BITMAPINFOHEADER),&numberOfBytesRead,NULL);//注意这里,把_lread函数换成了ReadFile函数
// now load the color palette if there is one
if (bitmap->bitmapinfoheader.biBitCount == 8)
{
// _lread(file_handle, &bitmap->palette,MAX_COLORS_PALETTE*sizeof(PALETTEENTRY));
ReadFile(file_handle,&bitmap->palette,MAX_COLORS_PALETTE*sizeof(PALETTEENTRY),&numberOfBytesRead,NULL);//注意这里,把_lread函数换成了ReadFile函数
// now set all the flags in the palette correctly and fix the reversed
// BGR RGBQUAD data format
//for (index=0; index < MAX_COLORS_PALETTE; index++)
// {
// // reverse the red and green fields
// int temp_color = bitmap->palette[index].peRed;
// bitmap->palette[index].peRed = bitmap->palette[index].peBlue;
// bitmap->palette[index].peBlue = temp_color;
//
// // always set the flags word to this
// bitmap->palette[index].peFlags = PC_NOCOLLAPSE;
// } // end for index //这段反转RGB顺序的代码貌似没什么意义,因为不管有没有这段代码,程序在Windows 7 x64下运行时显示的图像都是花的,不管是我编译出来的还是书上光盘自带的程序,都是花的...
} // end if
// finally the image data itself
//_lseek(file_handle,-(int)(bitmap->bitmapinfoheader.biSizeImage),SEEK_END); //这代码没搞懂,为什么到这里要移动一下文件指针呢?也没有找到对应Handle的seek函数,注释掉也能用.
// now read in the image, if the image is 8 or 16 bit then simply read it
// but if its 24 bit then read it into a temporary area and then convert
// it to a 16 bit image
if (bitmap->bitmapinfoheader.biBitCount==8 || bitmap->bitmapinfoheader.biBitCount==16 ||
bitmap->bitmapinfoheader.biBitCount==24)
{
// delete the last image if there was one
if (bitmap->buffer)
free(bitmap->buffer);
// allocate the memory for the image
if (!(bitmap->buffer = (UCHAR *)malloc(bitmap->bitmapinfoheader.biSizeImage)))
{
// close the file
//_lclose(file_handle);
CloseHandle(file_handle);//注意这里把_lclose函数换成了CloseHandle函数
// return error
return(0);
} // end if
// now read it in
//_lread(file_handle,bitmap->buffer,bitmap->bitmapinfoheader.biSizeImage);
ReadFile(file_handle,bitmap->buffer,bitmap->bitmapinfoheader.biSizeImage,&numberOfBytesRead,NULL);//注意这里,把_lread函数换成了ReadFile函数
} // end if
else
{
// serious problem
return(0);
} // end else
#if 0
// write the file info out
printf("\nfilename:%s \nsize=%d \nwidth=%d \nheight=%d \nbitsperpixel=%d \ncolors=%d \nimpcolors=%d",
filename,
bitmap->bitmapinfoheader.biSizeImage,
bitmap->bitmapinfoheader.biWidth,
bitmap->bitmapinfoheader.biHeight,
bitmap->bitmapinfoheader.biBitCount,
bitmap->bitmapinfoheader.biClrUsed,
bitmap->bitmapinfoheader.biClrImportant);
#endif
// close the file
//_lclose(file_handle);
CloseHandle(file_handle);//注意这里把_lclose函数换成了CloseHandle函数
// flip the bitmap
Flip_Bitmap(bitmap->buffer,
bitmap->bitmapinfoheader.biWidth*(bitmap->bitmapinfoheader.biBitCount/8),
bitmap->bitmapinfoheader.biHeight);
// return success
return(1);
} // end Load_Bitmap_File
运行结果:
程序刚启动的瞬间颜色是正常的,但是闪烁过后就变成花的了.暂时不知道什么原因,不过至少可以显示出图片了
XP下运行的效果,同样的,按ESC退出程序时也会变花.
虚拟XP下程序启动瞬间不会闪烁.
C#的一个好处就是几乎完全不用与二进制有关的东西和内存打交道,一切都是对象,一切都是十进制。突然转到C++,有点无所适从。现在记录一下半个月集中学习C++和DirectX的一些经验。
1、或运算(Or)符号:“|” ,与运算(And)符号:“&”。
在Window7系统自带计算器的程序员模式下可以找到这两个运算符。Windows7的计算器相当好用,输入的任何数都可以直观的表示出对应的二进制转换。
在C#中我们知道:
1 | 0 = 1
0 | 1 = 1
1 | 1 = 1
1 & 0 = 0
0 & 1 = 0
1 & 1 = 1
可以总结为:
与运算:两个数只要有一个为零则为零。
或运算:两个数只要有一个为一则为一。
这一法则不仅适用0和1,而且适用于任何数。
任意两个数 458 和 921 对应的二进制转换为:111001010,,1110011001。
运用上述法则:
0111001010 &
1110011001 =
0110001000
0111001010 |
1110011001 =
1111011011
以上是基础知识。
DirectX中有许多方法的参数名类似 xxFlag之类的东西。这时可以传入一些常量的或运算组合。比如:
lpdd->SetCooperativeLevel(main_window_handle,
DDSCL_ALLOWMODEX | DDSCL_FULLSCREEN |
DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT);
这种方法很有智慧,这些常量的值转换为二进制并进行与运算后就可以在一个数里面存储多个信息,比如
DDSCL_ALLOWMODEX = 1; //二进制:0001
DDSCL_FULLSCREEN = 2; //二进制:0010
DDSCL_EXCLUSIVE = 4; //二进制:0100
DDSCL_ALLOWREBOOT = 8; //二进制: 1000
OK,接下来把这四个选项进行与运算
0001
0010
0100
1000
= 1111
任意数量的选项的任意组合都不会重复,而且非常容易判断是否包含一个值.
判断方法就是用到与运算
int group = DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT;
现在我想判断 group里是否有包含DDSCL_EXCLUSIVE .
if (group & DDSCL_EXCLUSIVE)
{
//包含
}
else
{
//不包含
}
原理很简单.
DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT =
0100 |
1000 =
1100
1100 &
0100 =
0100 != 0 则为true
1100 &
1000 =
1000 != 0 则为true
而我们拿这个值和一个不包含在这个值里的数字进行与运算:
1100 &
0010 =
0000 = 0 则为false
2、移位运算符
左移: <<
右移:>>
很形象,很直观。
左移就是把一个数的二进制转换向左移动指定的位数。比如一个数
11111 << 1
把数11111向左移一位
结果为: 111110
同样的道理,把11111向右移一位
11111 >> 1
结果为: 1111
从二进制的角度来看十分简单.但如果转换到十进制就会有点困惑了.
其实从十进制角度来看也是有一规律的.
11111的十进制转换为31,左移一位的结果为62,左移两位的结果为124,左移三位的结果为:248.
规律出来了,左移1位等于乘以2,左移两位等于乘以2再乘以2,左移三位等于乘以2乘以2再乘以2
即左移位结果等于被移位数乘以2的移位数次方.
反过来右移就是做除法了.即右移位结果等于被移位数除以2乘以移位数次幂


