2017年4月27日 星期四

住宅樓宇按揭

住宅樓宇按揭

楼价$518万,首期20%即$103.6万

13 Mar 2017 付了现金$5万
28 Mar 2017 向律师楼交了支票$46.8万,以及$15.54万印花税支票
3 Apr 2017 是3星期后的首期付款日子,首期10%已经扣数
12 May 2017 成交日前要付楼价90%即$466.2万

楼价$518万,贷款80%即$414.4万,按揭保费$89096(2.15%)

按揭保费如何计算?
以按揭30年浮息按揭,一次付清保险费的保费为2.15%,每年支付的话是首年1.11%,其后0.28%。

Citibank提供的按揭内容:

户口是Citibanking而不是Citi Priority及Citigold,并且开立雇员理财计划(Citi At Work),包括货币理财组合(Currency Manager),以及港元「月月增息」支票储蓄户口(HKD Step-Up Interest Account / HKUA)。




Python traceback

import traceback

def ToTraceLines(ex, ex_traceback=None):
    if ex_traceback is None:
        ex_traceback = ex.__traceback__
    return [ line.rstrip('\n') for line in traceback.format_exception(ex.__class__, ex, ex_traceback)]
   
try:
    x = get_number()
except Exception as ex:
    ToTraceLines(ex)

2017年4月17日 星期一

dlopen and dlsym


Prepare a SO file writtern in C:
vi libso.c
#include <stdio.h>
int bejo_lib(char *name, int i) {
    printf("I am %s, do i=%d\n", name, i);
    return 0;
}
gcc -fPIC -c libso.c
gcc -shared -o libso.so libso.o

Notice the function name is not mangled because it is not C++:
nm libso.so  | grep bejo
00000000000006c8 T bejo_lib

Prepare the C user code:
vi use.c
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
int main(int argc, char **argv) {
    void* so = dlopen("./libso.so",RTLD_LAZY);
    printf("so: %p\n", so);
    if (!so) {
        fprintf(stderr, "%s\n", dlerror());
        exit(1);
    }
    dlerror();
    void (*fn)();
    fn = (void(*)())dlsym(so, "bejo_lib");
    printf("fn: %p\n", fn);
    if (fn) {
        fn("BEJO", 999);
    }
    dlclose(so);
    return 0;
}
// nm libso.so  | grep bejo
// 00000000000006c8 T bejo_lib
// gcc use.c -ldl -o use && ./use

The functions are mangled in the SO file libEsunnyQuot.so written in C++:
nm libEsunnyQuot.so | grep CreateEsunnyQuotClient
0000000000007c60 T _Z22CreateEsunnyQuotClientP17IEsunnyQuotNotify
nm libEsunnyQuot.so | grep DelEsunnyQuotClient
0000000000007c30 T _Z19DelEsunnyQuotClientP17IEsunnyQuotClient

Prepare the C++ user code:
vi sun.cpp
#include "EsunnyQuot.h"
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
int main(int argc, char **argv) {
    void* so = dlopen("./libEsunnyQuot.so",RTLD_LAZY);
    printf("so: %p\n", so);
    if (!so) {
        fprintf(stderr, "%s\n", dlerror());
        exit(1);
    }
    dlerror();
    void (*fn)(IEsunnyQuotClient*);
    fn = (void(*)(IEsunnyQuotClient*))dlsym(so, "_Z19DelEsunnyQuotClientP17IEsunnyQuotClient");
    printf("fn: %p\n", fn);
    if (fn) {
        fn(NULL);
    }
    dlclose(so);
    return 0;
}
// nm libEsunnyQuot.so | grep CreateEsunnyQuotClient
// 0000000000007c60 T _Z22CreateEsunnyQuotClientP17IEsunnyQuotNotify
// nm libEsunnyQuot.so | grep DelEsunnyQuotClient
// 0000000000007c30 T _Z19DelEsunnyQuotClientP17IEsunnyQuotClient
// gcc sun.cpp -ldl -o sun && ./sun

2017年4月11日 星期二

【谨慎使用】解决CTP在Linux开发中double free

原创文章,转载请注明: 转载自勤奋的小青蛙
本文链接地址: 【谨慎使用】解决CTP在Linux开发中double free
感谢网友:∮f(x)dx,徐冠鹏 提供的解决方法。
这份代码用于演示如何利用 dlopen 来避免 CTP GNU/Linux API 中 trader 和 mduser 两个库同时在一个进程中加载导致的 double free 问题。请注意,它只
用于演示如何避免 double free,其余为了能使这个程序能运行起来的代码没有任何实际意义,且不适合用于生产。所以这份代码仅供参考,因使用此代码引起
的任何损失,我不承担任何责任。
精力所限,下述的步骤的测试环境包含:
- 64 位 Gentoo Linux,内核版本 3.17.7-gentoo
- GCC Gentoo 4.8.3 p1.1, pie-0.5.9
- CTP GNU/Linux 版 6.3.0_20140811
1. 下载 http://www.sfit.com.cn/DocumentDown/api/6.3.0_20140811_traderapi_linux.tar并解压至工作目录:
?
1
2
3
4
5
6
7
$ mkdir work
$ cd work
work
$ wget http://www.sfit.com.cn/DocumentDown/api/6.3.0_20140811_traderapi_linux.tar
work $ tar xf 6.3.0_20140811_traderapi_linux.tar
work $ ls
6.3.0_20140811_traderapi_linux.tar  6.3.0_20140811_traderapi_linux32  6.3.0_20140811_traderapi_linux64
2. 将 Makefile、md_test.cc、trader_test.cc、x.cc 复制至包含 CTP 头文件及共享库的目录。这里是 64 位 GNU/Linux 的目录:
?
1
2
$ cd 6.3.0_20140811_traderapi_linux64
$ cp .../{Makefile,md_test.cc,trader_test.cc,x.cc} .
这里需要把 "..." 换成包含这些文件的目录。
3. 重命名共享库文件:
?
1
2
$ mv thostmduserapi.so libthostmduserapi.so
$ mv thosttraderapi.so libthosttraderapi.so
4. 编译。这可以用 make 完成:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ make
g++ -g -fPIC   -c -o x.o x.cc
c++ -g -fPIC -o x x.o -ldl
g++ -g -fPIC   -c -o trader_test.o trader_test.cc
trader_test.cc: In function 'void init()':
trader_test.cc:69:88: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
                                                                                        ^
g++ -fPIC -shared -o libtrader_test.so trader_test.o -L. -lthosttraderapi -ldl
g++ -g -fPIC   -c -o md_test.o md_test.cc
md_test.cc: In function 'void init()':
md_test.cc:75:88: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
                                                                                        ^
g++ -fPIC -shared -o libmd_test.so md_test.o -L. -lthostmduserapi -ldl
5. 运行:
?
1
2
3
4
5
6
7
8
9
$ LD_LIBRARY_PATH=. ./x
trader front connected
wlp3s0: Success
md front connected
wlp3s0: Success
TRADER: 3: 综合交易平台:不合法的登录
MD: 3: 综合交易平台:不合法的登录
CThostFtdcUserApiImplBase::OnSessionDisconnected[0x7f80300008c8][1510735873][    0]
CThostFtdcUserApiImplBase::OnSessionDisconnected[0x7f802c0008c8][1510735873][    0]
6. 说明:
trader_test.cc 中包含一个 trader SPI 的实现,编译后生成libtrader_test.so。md_test.cc 中包含一个 md SPI 的实现,编译后生成libmd_test.so。这两个文件各自使用 dlopen 加载对应的 CTP 共享库,并用RTLD_DEEPBIND 隔离两个共享库中冲突的符号。
x.cc 通过加载 libtrader_test.so 和 libmd_test.so 来使用 CTP 的功能。运行时,需要确保所有的共享库存在于系统搜索共享库的目录中,这可以通过配置ld.so.conf 或设置 LD_LIBRARY_PATH 环境变量来实现。配置 ld.so.conf 的方法请参考各发行版的手册,LD_LIBRARY_PATH 的设置方法见上面的例子。
Makefile
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
CXXFLAGS += -g -fPIC
 
all:    x libtrader_test.so libmd_test.so
 
x:  x.o
    c++ $(CXXFLAGS) -o x x.o -ldl
 
libtrader_test.so:  trader_test.o
    $(CXX) -fPIC -shared -o libtrader_test.so trader_test.o -L. -lthosttraderapi -ldl
 
libmd_test.so:  md_test.o
    $(CXX) -fPIC -shared -o libmd_test.so md_test.o -L. -lthostmduserapi -ldl
 
clean:
    rm -f x *.o
md_test.cc
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <unistd.h>
#include <dlfcn.h>
 
#include "ThostFtdcMdApi.h"
 
using namespace std;
 
volatile int child_finished = 0;
 
volatile int logging_in = 0;
 
class SimpleHandler: public CThostFtdcMdSpi
{
  CThostFtdcMdApi *user_api;
 
public:
 
  SimpleHandler (CThostFtdcMdApi *user_api): user_api (user_api) { }
 
  ~SimpleHandler () { }
 
  virtual void OnFrontConnected ()
  {
    if (!logging_in++)
      {
    printf ("md front connected\n");
    CThostFtdcReqUserLoginField user_login_req;
    strcpy (user_login_req.BrokerID, "test_uid");
    strcpy (user_login_req.UserID, "test_uid");
    strcpy (user_login_req.Password, "password");
    user_api->ReqUserLogin (&user_login_req, 0);
      }
  }
 
  virtual void OnFrontDisconnected (int reason)
  {
    printf ("md front disconnected: %d\n", reason);
  }
 
  virtual void OnRspUserLogin (CThostFtdcRspUserLoginField *resp,
                   CThostFtdcRspInfoField *info,
                   int req_id, bool is_last)
  {
    printf ("MD: %d: %s\n", info->ErrorID, info->ErrorMsg);
    if (info->ErrorID != 0)
      child_finished = 1;
  }
};
 
CThostFtdcMdApi *user_api;
 
SimpleHandler *simple_handler;
 
extern "C"
{
 
void
init ()
{
  void *trader_user_handle = dlopen ("libthostmduserapi.so",
                     RTLD_LAZY | RTLD_DEEPBIND);
  if (trader_user_handle == 0)
    {
      fprintf (stderr, "Cannot load libthostusermdapi.so\n");
      exit (-1);
    }
 
  user_api = CThostFtdcMdApi::CreateFtdcMdApi ();
 
  simple_handler = new SimpleHandler (user_api);
  user_api->RegisterSpi (simple_handler);
  user_api->Init ();
}
 
void
finalize ()
{
  user_api->RegisterSpi (0);
  user_api->Release ();
  delete simple_handler;
  simple_handler = 0;
}
 
}
trader_test.cc
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <unistd.h>
#include <dlfcn.h>
 
#include "ThostFtdcTraderApi.h"
 
using namespace std;
 
volatile int child_finished = 0;
 
class SimpleHandler: public CThostFtdcTraderSpi
{
  CThostFtdcTraderApi *user_api;
 
public:
 
  SimpleHandler (CThostFtdcTraderApi *user_api): user_api (user_api) { }
 
  ~SimpleHandler () { }
 
  virtual void OnFrontConnected ()
  {
    printf ("trader front connected\n");
    CThostFtdcReqUserLoginField user_login_req;
    strcpy (user_login_req.BrokerID, "test_uid");
    strcpy (user_login_req.UserID, "test_uid");
    strcpy (user_login_req.Password, "password");
    user_api->ReqUserLogin (&user_login_req, 0);
  }
 
  virtual void OnFrontDisconnected (int reason)
  {
    printf ("trader front disconnected: %d\n", reason);
  }
 
  virtual void OnRspUserLogin (CThostFtdcRspUserLoginField *resp,
                   CThostFtdcRspInfoField *info,
                   int req_id, bool is_last)
  {
    printf ("TRADER: %d: %s\n", info->ErrorID, info->ErrorMsg);
  }
};
 
CThostFtdcTraderApi *user_api;
SimpleHandler *simple_handler;
 
extern "C"
{
 
void
init ()
{
  void *trader_user_handle = dlopen ("libthosttraderapi.so",
                     RTLD_LAZY | RTLD_DEEPBIND);
  if (trader_user_handle == 0)
    {
      fprintf (stderr, "Cannot load libthosttraderapi.so\n");
      exit (-1);
    }
 
  user_api = CThostFtdcTraderApi::CreateFtdcTraderApi ();
 
  simple_handler = new SimpleHandler (user_api);
  user_api->RegisterSpi (simple_handler);
  user_api->SubscribePrivateTopic (THOST_TERT_RESUME);
  user_api->SubscribePublicTopic (THOST_TERT_RESUME);
  user_api->Init ();
}
 
void
finalize ()
{
  user_api->RegisterSpi (0);
  user_api->Release ();
  delete simple_handler;
  simple_handler = 0;
}
 
}
x.cc
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <unistd.h>
#include <dlfcn.h>
 
using namespace std;
 
int
main (int argc, char *argv[])
{
  void *trader_handle = dlopen ("libtrader_test.so", RTLD_LAZY);
  if (trader_handle == 0)
    {
      fprintf (stderr, "Cannot load libtrader_test.so\n");
      exit (-1);
    }
 
  void (*trader_init)() = (void (*)()) dlsym (trader_handle, "init");
  void (*trader_finalize)() = (void (*)()) dlsym (trader_handle, "finalize");
  trader_init ();
 
  void *md_handle = dlopen ("libmd_test.so", RTLD_LAZY);
  if (md_handle == 0)
    {
      fprintf (stderr, "Cannot load libmd_test.so\n");
      exit (-1);
    }
 
  void (*md_init)() = (void (*)()) dlsym (md_handle, "init");
  void (*md_finalize)() = (void (*)()) dlsym (md_handle, "finalize");
  md_init ();
 
  sleep (3);
 
  md_finalize ();
  trader_finalize ();
 
  return 0;
}
原创文章,转载请注明: 转载自勤奋的小青蛙
本文链接地址: 【谨慎使用】解决CTP在Linux开发中double free

2007 to 2023 HP and Dell Servers Comparison

  HP Gen5 to Gen11  using ChatGPT HP ProLiant Gen Active Years CPU Socket Popular HP CPUs Cores Base Clock Max RAM Capacity Comparable Dell ...