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

2023 Promox on Morefine N6000 16GB 512GB

2023 Promox on Morefine N6000 16GB 512GB Software Etcher 100MB (not but can be rufus-4.3.exe 1.4MB) Proxmox VE 7.4 ISO Installer (1st ISO re...