Installing 64 bits Operation System

我工作用的计算机是32位的intel cpu,最近要用虚拟机安装64位的操作系统,本来以为是不可能解决的问题,没想到intel有一种技术叫Virtualization Technology,可以解决此问题,只要将BIOS里的VT选项打开,即可以在32位机器上正常安装64位的操作系统了。

Comments (1)

How to avoid “Error writing output file” in C++ Builder 6

在C++ Builder6编译程序的时,有时会出现”Error writing output file”的错误,通常情况下,是由于某个OBJ文件或者TDS文件被锁定(如属性是只读,或者被其他程序使用),解决方法也很简单,直接删除掉这些文件即可,如果删不掉的话,那就先关闭C++ Builder或者其他应用程序再试。

Leave a Comment

How to avoid E2015 Ambiguity between ‘ULONG_PTR’ and “Wmplib_tlb::ULONG_PTR’

近日在程序里引用了windows media player组件,编译程序报了E2015的错。

E2015 Ambiguity between ‘ULONG_PTR’ and “Wmplib_tlb::ULONG_PTR’

解决方法很多,个人觉得最一劳永逸的方法是直接修改Wmplib_tlb.h,把里面所有的Wmplib_tlb::ULONG_PTR全部替换为ULONG_PTR

注:此问题只存在于在C++Builder中导入Windows Media Player时,其他情况下不一定会发生。

Leave a Comment

Tips about calling stored procedure from Oracle pro*c

今天写一个测试程序,实验一下在pro*c里面调用存储过程,程序写好之后,发现预编译总是报错,错误代码是PCC-S-02022和PCC-F-02102,这两个错误看起来跟连锁错误一样。后来发现有如下几点需要注意的:
1、END-EXEC和END_EXEC
有部分教材的代码上写的是END_EXEC,不知道是不是教材陈旧,还是印刷错误,反正我查证之后发现应该写成END-EXEC才对。

2、proc编译选项
这个很重要,我曾经被次困扰了很长时间,我现在使用的选项如下
proc iname=test.cp include=./include userid=test/123456 mode=ansi code=ansi_c parse=full dynamic=ansi type_code=ansi ltype=none sqlcheck=full
其中sqlcheck=semantics也可以。但一定要保证userid的选项正确填写,否则肯定报错。

Leave a Comment

SQLITE3的C++简单封装类

几年前写过一个简单的sqlite3读写,非常简陋,bug在所难免,旨在给初学者一点帮助,欢迎高手交流


// mySQLITE3.hpp
// 该文件在visual c++ 6.0和c++ builder 6.0上均编译通过,在我自己的程序上运行好几年了
#ifndef __MY_SQLITE3_HPP__
#define __MY_SQLITE3_HPP__
#include "sqlite3_lib\sqlite3.h"
#ifdef
//---------------------------------------------------------------------------
class TMySQLite3
{
private:
sqlite3* _db; // 数据库实例
char* _errmsg; // 错误信息
char** _dbResult; // 记录集
public:
TMySQLite3() { _db=NULL; _errmsg=NULL; }
// 释放时,要先释放表并关闭数据库
~TMySQLite3() {
if (_dbResult) {
sqlite3_free_table(_dbResult);
}
if (_db) {
sqlite3_close(_db);
}
}
// 打开数据库
bool OpenDB(char* FullDBPath) {
int result = sqlite3_open(FullDBPath, &_db);
if (result!=SQLITE_OK) return false;
return true;
}
// 取数据记录
char** FetchRecord(char* SQL, int* Row, int* Col) {
int result = sqlite3_get_table(_db, SQL, &_dbResult, Row, Col, &_errmsg);
if (result==SQLITE_OK) return _dbResult;
else return NULL;
}
// 释放记录集
void FreeRecord() {
sqlite3_free_table(_dbResult);
_dbResult = NULL;
}
// 执行SQL语句
bool ExecSQL(char* SQL) {
int result = sqlite3_exec(_db, SQL, NULL, NULL, &_errmsg);
if (result!=SQLITE_OK) return false;
return true;
}
// 取得错误信息
char* GetMessage() {
return _errmsg;
}
};

#endif

下面是一段测试代码,Visual C++ 6.0的工程里面提炼出来的,供参考。

TMySQLite3 *pLite;
pLite = new TMySQLite3(); // 创建实例
// 打开数据库文件
if (pLite->OpenDB("E:\\task.db")==false) {
AfxMessageBox(pLite->GetMessage());
}
char** rs = NULL;
int nRow=0, nCol=0;
// 打开数据集
rs = pLite->FetchRecord("select * from t_task", &nRow, &nCol);
if (rs==NULL) AfxMessageBox(pLite->GetMessage());
else {
int nIndex=nCol;
// 循环输出每行数据
for (int i=0; i<nRow; i++) {
fprintf(stderr, "[%s]\t-\t[%s]\t-\t[%s]", rs[nIndex], rs[nIndex+1], rs[nIndex+2]);
nIndex += nCol;
}
pLite->FreeRecord();
}
if (pLite) {
delete pLite;
pLite = NULL;
}

t_task的建表脚本可以如下

CREATE TABLE t_task
(
taskid    integer not null,
tasktitle varchar(255) not null,
tasktype  char(2) not null,
taskdate  char(8) null
)
CREATE UNIQUE INDEX idx_task ON t_task(taskid)

Leave a Comment

POP3 with OpenSSL 0.9.8

自己写了一个小工具,用来检测POP3信箱是否有新邮件到了(其实邮件客户端outlook、foxmail等都可以检测,但不想在电脑上开太多的程序,所以自己写了一个),我一直用来检测公司邮箱,用得很好。前两天老婆说要用来检测gmail邮箱的邮件,却一直没反应,研究了一下gmail的说明,发现gmail的pop3需要ssl加密连接,所以就研究了一下OpenSSL的安装和使用

下载openssl-0.9.8.tar.gz,解压后,可以查看INSTALL.W32这个文件,告诉你在windows环境下如何编译和安装。

安装openssl之前你必须先安装Active Perl(http://www.activestate.com/ActivePerl)和NASM(http://www.kernel.org/pub/software/devel/nasm/binaries/win32/)(或者MASN,手册上说windows DDK里面包含了MASM,但是windows DDK不容易找,直接找MASM可能更容易些,比如asm.yeah.net里面就有下载的)。

我是在Borland C++ Builder 6环境下编译的,VC的方法也差不多。

进入到openssl解压后的目录,该目录下应该包含有README,NEWS等等文件,在windows控制台逐步执行下列步骤

> perl Configure BC-32
生成配置文件

> ms\do_nasm
生成makefile

> make -f ms\bcb.mak
生成结果

最终得到的lib文件在out32目录下,分别是libeay32.lib和ssleay32.lib
开发所用到的头文件在inc32目录下,你可以把这些文件组合到你同一个目录,以方便配置编译器选项

下面是一段用pop3来连接gmail的例子,供参考。


//---------------------------------------------------------------------------
// NOTE!!!
// Change gmail account and password first before begin test.
//---------------------------------------------------------------------------
#include "vcl.h"
#pragma hdrstop
#include "stdlib.h"
#include "stdio.h"
#include "conio.h"
#include "winsock2.h"
#include "openssl/ssl.h"
#include "openssl/bio.h"
#include "openssl/err.h"
//---------------------------------------------------------------------------
#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "openssl\\libeay32.lib")
#pragma comment(lib, "openssl\\ssleay32.lib")

#pragma warn-8004
#pragma argsused

int main(int argc, char* argv[])
{
SSL * ssl;
SSL_CTX * ctx;
SOCKET sock;
char* hostname = "pop.gmail.com";
int port = 995;

fprintf(stdout, "HOST: %s\t PORT: %d\nConnecting, standby...", hostname, port);
// start winsock
WSAData ws;
WSAStartup(0x0101, &ws);

unsigned long ip = inet_addr(hostname);
hostent* h_entity;
if (ip == 0xFFFFFFFF) {
h_entity = gethostbyname(hostname);
if (!h_entity) {
fprintf(stdout, "Can't reach the host\n");
return -1;
}
memcpy(&ip, h_entity->h_addr_list[0], sizeof(int));
}

// create socket and connect to server
sockaddr_in server;
memcpy(&server.sin_addr, &ip, sizeof(int));
server.sin_port = htons(port);
server.sin_family = AF_INET;
memset(&server.sin_zero, 0x00, 0x08);
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
connect(sock, (sockaddr*)&server, sizeof(server));

// Load ssl context with socket binded
SSL_library_init();
SSL_load_error_strings();
ctx = SSL_CTX_new(SSLv23_client_method());
ssl = SSL_new(ctx);
SSL_set_fd(ssl, sock);
int sslErr = SSL_connect(ssl);

char buff[1024];

// Read welcome info
memset(buff, 0x0, sizeof(buff));
int total = SSL_read(ssl, buff, 1023);
fprintf(stdout, "\n%s", buff);

// Send account
char* p = "USER youraccount@gmail.com\r\n";
SSL_write(ssl, p, strlen(p));

memset(buff, 0x0, sizeof(buff));
total = SSL_read(ssl, buff, 1023);
fprintf(stdout, "\n%s", buff);

// Send password
p = "PASS yourpassword\r\n";
SSL_write(ssl, p, strlen(p));
memset(buff, 0x0, sizeof(buff));
total = SSL_read(ssl, buff, 1023);
fprintf(stdout, "%s", buff);

fprintf(stdout, "Disconnect from the server.\nPress any key to exit.\n");
getch();

// Clear and free
SSL_shutdown(ssl);
closesocket(sock);
SSL_free(ssl);
SSL_CTX_free(ctx);
WSACleanup();
return 0;
}

Comments (3)

two decimal reserved, without any zero rounded

用C++Builder的QuickReport组件做几个报表,要求在查询的结果中所有的金额字段都要保留两位小数,并且不能丢失小数点后面的0。我用TListView呈现查询结果,用TQuickReport来设计报表样式。数据库是Sybase。

将查询结果直接填入到TListView之后,发现小数点后面是没有精度的,于是将查询语句里面加入了数据类型转换,如下:

SELECT convert(decimal(13,2), amount) FROM anytable

在DBArtisan里面显示的结果没有问题,然后放到C++Builder里面执行,填入TListView里面还是舍掉了后面的0,没想到好办法,就用如下代码:

char buff[15];
sprintf(buff, "%.02f", anyQry->FieldByName("amount")->AsFloat);

来转换,再填充到TListView。

而对于TQuickReport,本来以为很难搞,后来发现TQRDBText有一个属性叫Mask,设置为0.00,就可以起作用了。

Leave a Comment

Older Posts »