Error

C++博客 首页 新随笔 联系 聚合 管理
  217 Posts :: 61 Stories :: 32 Comments :: 0 Trackbacks

#

运行时使用非标准位置/usr/lib和/lib下的库的方式有三种:
(1) 设置$LD_LIBRARY_PATH=库所在目录(多个目录用:分隔),系统加载工具ld.so/ld-linux.so将顺序搜索变量指定的目录。例如#$LD_LIBRARY_PATH=/usr/local/mysql/lib ./test_mysql
(2) 以root身份把库路径加入/etc/ld.so.conf或在/etc/ld.so.conf.d中创建特定的.conf文件,然后运行ldconfig更新/etc/ld.so.cache。例如:在/etc/ld.so.conf.d下创建文件mysql.conf写入/usr/local/mysql/lib
(3) 另一种办法就是把需要的库copy到/usr/lib或/lib,但这不是建议的方法,特别是尽量避免copy发到/lib。但这种方法可以在编译时免去用-L选项。



linux中动态链接库的搜索顺序

 (2008-12-23 10:03:20)
标签: 

杂谈

linux中动态链接库的搜索顺序 
//
// by kirk,2008.11.21,文中有bug请搞紧与我联系:-)
//   
  

    在接手一个很古老的程序时,发现其所使用的动态库都实在是太陈旧了,正式运行环境中部署的库都是相适应的,而目前的开发测试环境中均是部署的新的升级版本。为了能在这些环境下开发测试,程序得能在自定义的路径里来搜索。因此在这里复习一下linux中程序对动态链接库的搜索顺序,如下所述:

   1.首先查看程序文件的.dynamic 段是否包含了一个叫DT_RPATH的项(它是一个以冒号分隔的库文件搜索目录列表)。

   怎么设置这个选项?

   需要在编译连接程序的时候使用-Wl,-rpath选项,假设一个程序test需要使用liblib.so库,如下所示进行编译连接:

    

g++ -o test -L. -llib -Wl,rpath=./ test.cpp
 

     这样在执行test程序时,test便会先到./即当前目录下查找所需要的动态库liblib.so

    2.查找是否存在环境变量 LD_LIBRARY_PATH(它是一个以冒号分隔的库文件搜索目录列表)。

   怎么设置这个选项?当然是设置linux下的环境变量就可以了。

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:./
 

      当然,这种方法是对当前登录生效的。如果想开机即有效,跟其它环境变量的设置也是一样,需要修改一些配置文件。

    3.查看库高速缓存文件 /etc/ld.so.conf ,它包含了库名和路径的一个对应列表,如果库名存在,连接器就使用它对应的路径,用这个查找方法能够找到大部分的库。

   怎么设置这个选项?可以直接编辑ld.so.conf加入需要查找的路径,也可以在/etc/ld.so.conf.d目录下的己有文件中加入路径,或者在该目录下新建一个文件(名字为*.conf即可),再把需要的路径加入到该文件中。最后执行ldconfig即可生效。

    4.查找默认路径/lib和/usr/lib,

    如果经过了以上的步骤仍然查找失败,则将报错并退出相关程序。

    对于前三个步骤来说,我们均是可以进行设置调整的,其中第三个步骤中的设置需要root权限才能进行,且会影响所有的程序。当使用第一、第二中的方法进行了设置调整后,我们便可以使多种版本的库共存在同一环境下进行测试,同名也无所谓。
 *********************************************************************

环境变量LD_LIBRARY_PATH用来指定查找共享库时除了默认路径之外的其他路径。(该路径在默认路径之前查找)
移植程序时的经常碰到需要使用一些特定的动态库,而这些编译好的动态库放在我们自己建立的目录里,这时我们可以设置LD_LIBRARY_PATH
例:export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/work/lib/
这样就可以使用/work/lib/下的库文件了,运行程序后系统会自动到环境变量LD_LIBRARY_PATH指定的路径中查找其所需的库。
系统查找动态库的顺序
系统先找LD_LIBRARY_PATH下的库再找/lib and /usr/lib等路径下的库,还有/etc/ld.so.conf里指定的路径(如果ld.so.conf存在),man ldconfig for more information
[url=http://infomax/bbs/misc.php?action=viewratings&tid=111&pid=228][/url]
使Linux启动之后就加载LD_LIBRARY_PATH的路径
/etc/rc.d/rc.local文件中加入export   LD_LIBRARY_PATH="xxxxx"  即可
如果在链接时使用了"-R"和"-L"选项,则相关动态库的路径将保存在ELF文件中,于
是以后的运行中不再需要设置环境变量去定位动态库。比如,有一个
/usr/local/lib/libfoo.so,而你的bar程序需要这个libfoo.so,编译、链接时最好
这样 :gcc -Wall -pipe -O3 -o bar -R/usr/local/lib -L/usr/local/lib bar.c -lfoo
(#man gcc ,没发现-R或-rpath选项,待查)


posted @ 2015-08-18 17:42 Enic 阅读(1090) | 评论 (0)编辑 收藏

require("wx")
--文档需要结合wxWidget和wxLua来看,wxLua中明确的指定的导出的接口名字有些和wxWidget中不一样
--wx.wxFrame只有一个子空间的时候会自动拉伸,所以用DLG把
dlg = wx.wxDialog(wx.NULL, wx.wxID_ANY, "wxLua例子",
                   wx.wxDefaultPosition, wx.wxSize(450,450),
                   wx.wxDEFAULT_FRAME_STYLE)
--创建新的ID
local ID_BTN_0 = wx.wxNewId();
local ID_BTN_1 = wx.wxNewId();
--使用ID创建button
btn = wx.wxButton(dlg, ID_BTN_0, "Button", wx.wxPoint(90,0), wx.wxSize(30,60))
btn:SetSize(wx.wxSize(30,60))
--btn:SetPosition(wx.wxPoint(0,0))
--设置按钮事件
dlg:Connect(ID_BTN_1, wx.wxEVT_COMMAND_BUTTON_CLICKED,
    function(event) 
        wx.wxMessageBox("", "1")
    end
)
--C++版sdk是SetPositon,这里必须用move,很奇怪
btn1 = wx.wxButton(dlg, ID_BTN_1, "Button1", wx.wxPoint(0,0), wx.wxSize(30,60))
btn1:Move(wx.wxPoint(99,99))
dlg:Move(wx.wxPoint(99,99))
dlg:Show(true)
wx.wxGetApp():MainLoop()
posted @ 2015-08-14 15:43 Enic 阅读(601) | 评论 (0)编辑 收藏

TCP之选项TCP_KETEPALIVE
 
KEEPALIVE机制,是TCP协议规定的TCP层(非应用层业务代码实现的)检测TCP本端到对方主机的TCP连接的连通性的行为。避免服务器在客户端出现各种不良状况时无法感知,而永远等在这条TCP连接上。
 
该选项可以设置这个检测行为的细节,如下代码所示:
int keepAlive = 1;    // 非0值,开启keepalive属性
int keepIdle = 60;    // 如该连接在60秒内没有任何数据往来,则进行此TCP层的探测
int keepInterval = 5; // 探测发包间隔为5秒
int keepCount = 3;        // 尝试探测的次数.如果第1次探测包就收到响应了,则后2次的不再发
setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (void *)&keepAlive, sizeof(keepAlive));
setsockopt(sockfd, SOL_TCP, TCP_KEEPIDLE, (void*)&keepIdle, sizeof(keepIdle));
setsockopt(sockfd, SOL_TCP, TCP_KEEPINTVL, (void *)&keepInterval, sizeof(keepInterval));
setsockopt(sockfd, SOL_TCP, TCP_KEEPCNT, (void *)&keepCount, sizeof(keepCount));
 
设置该选项后,如果60秒内在此套接口所对应连接的任一方向都没有数据交换,TCP层就自动给对方发一个保活探测分节(keepalive probe)。这是一个对方必须响应的TCP分节。它会导致以下三种情况:
    对方接收一切正常:以期望的ACK响应。60秒后,TCP将重新开始下一轮探测。
    对方已崩溃且已重新启动:以RST响应。套接口的待处理错误被置为ECONNRESET。
    对方无任何响应:比如客户端那边已经断网,或者客户端直接死机。以设定的时间间隔尝试3次,无响应就放弃。套接口的待处理错误被置为ETIMEOUT。
 
全局设置可更改/etc/sysctl.conf,加上:
net.ipv4.tcp_keepalive_intvl = 5
net.ipv4.tcp_keepalive_probes = 3
net.ipv4.tcp_keepalive_time = 60
 
在程序中表现为:
阻塞模型下,当TCP层检测到对端socket不再可用时,内核无法主动通知应用层出错,只有应用层主动调用read()或者write()这样的IO系统调用时,内核才会利用出错来通知应用层。
非阻塞模型下,select或者epoll会返回sockfd可读,应用层对其进行读取时,read()会报错。
 
一点经验:
实际上我们在做服务器程序的时候,对客户端的保活探测基本上不依赖于这个TCP层的keepalive探测机制。
而是我们自己做一套应用层的请求应答消息,在应用层实现这样一个功能。



在Window上遇到这个问题,最后发现貌似只支持:
               // 设置KEEPALIVE (开启检测)
int optval = 1;
setsockopt(m_hSocket, SOL_SOCKET, SO_KEEPALIVE, (char *) &optval, sizeof(optval));


然后实际断开是在主动Recv或者Send调用后才触发的
posted @ 2015-07-22 17:48 Enic 阅读(208) | 评论 (0)编辑 收藏

FileUtils::setPopupNotify()  // 图片加载失败后,弹出message box提示
xpcall(main, __G__TRACKBACK__)   // xpcall( 调用函数, 错误捕获函数 ); 
package.path = package.path .. ";src/"  // ..是连字符,和win path一样;风格,表示添加目录src
require("app.MyApp").new():run()  // 加载app目录的MyApp文件,类似dofile,然后调用new方法调用默认的构造函数MyApp:ctor()在调用成员函数run
cc.FileUtils:getInstance():addSearchPath("res/")  // 添加搜索路径
self:enterScene("MainScene")  // 调用 AppBase:enterScene相当于 
//self.packageRoot = packageRoot or "app"   -- 这里的or类似C语言的?:用法,所以默认是app
//self.packageRoot .. ".scenes." .. sceneNamelocal 
//sceneClass = require(scenePackageName)
cc.ui.UILabel看源代码,发现lua是“动态类型,必须转变cpp的思想”。cc.ui.UILabel.new实际的基类是根据参数决定的,lua代码提供若然扩展方法,基类根据参数决定了以后还可以拥有基类的方法
最终是通过display.newBMFontLabel等函数创建的。
class("UILabel", function(options) return XX end),表示类UILabel继承于后面的函数返回的对象。相当于给后面函数产生的原表附加当前给定的原表信息
 

printInfo('run')  -- cocos也有分级日志,
printLog(tag, fmt, ...)
printError(fmt, ...)
dump_value_(v)


dump(self)  --类似php的dump函数,用于输出复杂变量
posted @ 2015-07-17 18:54 Enic 阅读(198) | 评论 (0)编辑 收藏

大神的解释:

Immediate Mode GUI (IMGUI)。这种类型的更多的适用于显示区域实时刷新的程序里面,例如游戏和CAD等。
Retained Mode GUI (RMGUI)


用一个传统RMGUI库的时候,用户往往需要显式的初始化每一个控件对象。每个控件都是存在内存中的实体,并且每个控件都需要自己保存一部分数据(例如一个slider需要保存一个数值,Button要保存一个回调事件等),用户还需要在一个回调函数里将控件里的数据拷贝回程序本身中(MVC模式)。

IMGUI模式在使用上会更简单粗暴一些。控件没有自己的对象,不保存任何状态,不用单独的去实现UI和程序间数据的交换,甚至都不需要单独为事件写回调函数。每个控件就是一个函数,直接在程序的Draw()函数里要哪个控件就调用哪个函数就好了。



posted @ 2015-06-25 13:49 Enic 阅读(960) | 评论 (0)编辑 收藏

reg add "HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers" /v "c:\windows\system32\cmd.exe" /d "RUNASADMIN" /f
reg add "HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers" /v "C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\devenv.exe" /d "RUNASADMIN" /f


问题描述:

  打开VS2012项目时,提示保存“devenv.sln”

 

解决方法:

  找到文件:C:\Program Files (x86)\Common Files\microsoft shared\MSEnv\vslauncher.exe

  鼠标右键设置“兼容性”->“以管理员身份运行此程序”即可

posted @ 2015-06-20 13:03 Enic 阅读(202) | 评论 (0)编辑 收藏

理解三个函数:release  retain  autorelease
对应的有两个计数器:ref  autoref
autorelease是委托pool管理器在某个时候执行release

话说cocos默认的create方法会创建完成以后立刻、马上执行一次autorelease,行为有点诡异,而且new出来只有ref值是1
作为规范,create以后应该马上autorelease和init否则坑爹
 1  
 2 template <typename TVal>
 3 xcc::RefPtr<TVal> TMakeRefPtr()
 4 {
 5     TVal* pRefTem = new TVal;
 6     xcc::RefPtr<TVal> rpTem = pRefTem;
 7     rpTem->init();
 8     rpTem->autorelease();
 9 
10     return rpTem;
11 }

顺便放一个用于cocos的智能指针: 1 // cocos2d
 2 template<typename TCocosRefVal>
 3 class RefPtr
 4 {
 5 public:
 6     RefPtr(TCocosRefVal* pRefVal = NULL)
 7     {
 8         m_pRefVal = pRefVal;
 9         __IncRef();
10     }
11 
12     RefPtr(const RefPtr<TCocosRefVal>& refVal)
13     {
14         m_pRefVal = pRefVal;
15         __IncRef();
16     }
17 
18     RefPtr(RefPtr<TCocosRefVal>&& refVal)
19     {
20         m_pRefVal = refVal.m_pRefVal;
21 
22         refVal.m_pRefVal = NULL;
23     }
24 
25     virtual ~RefPtr()
26     {
27         __DecRef();
28     }
29 
30     virtual const RefPtr& operator = (const RefPtr<TCocosRefVal>& refVal)
31     {
32         if (m_pRefVal != refVal.m_pRefVal)
33         {
34             Reset(refVal.m_pRefVal);
35         }
36 
37         return *this;
38     }
39 
40     virtual void Reset(TCocosRefVal* pRefVal = NULL)
41     {
42         __DecRef();
43         m_pRefVal = pRefVal;
44         __IncRef();
45     }
46 
47     virtual bool operator == (const RefPtr<TCocosRefVal>& refVal)
48     {
49         return (m_pRefVal != refVal.m_pRefVal);
50     }
51 
52     virtual TCocosRefVal* Get() const 
53     {
54         return m_pRefVal;
55     }
56 
57     virtual operator TCocosRefVal*() const
58     {
59         return m_pRefVal;
60     }
61 
62     virtual TCocosRefVal* operator -> () const
63     {
64         return m_pRefVal;
65     }
66 
67     virtual TCocosRefVal& operator * () const
68     {
69         return *m_pRefVal;
70     }
71 
72 protected:
73     void __IncRef()
74     {
75         if (NULL != m_pRefVal)
76         {
77             m_pRefVal->retain();
78         }
79     }
80 
81     void __DecRef()
82     {
83         if (NULL != m_pRefVal)
84         {
85             CCAssert(m_pRefVal->retainCount() >= 1, "");
86             m_pRefVal->release();
87         }
88     }
89 
90 private:
91     TCocosRefVal* m_pRefVal;
92 };
posted @ 2015-06-06 21:28 Enic 阅读(162) | 评论 (0)编辑 收藏

void FixWorkingDir()
{
HANDLE hCurrentExe = ::GetModuleHandle(NULL);
std::tstring strFileName;
std::tstring strPath;
strFileName.resize(MAX_PATH*2, 0);
::GetModuleFileName((HMODULE)hCurrentExe, const_cast<TCHAR*>(strFileName.data()), strFileName.size());
auto nPosEnd = strFileName.find_last_of(_T('\\'));
if (std::tstring::npos != nPosEnd)
{
strPath = strFileName.substr(0, nPosEnd);
::SetCurrentDirectory(strPath.c_str());
}
else
{
XASSERT_MSG(false, _T("windows did not have root path, \\ must be found"));
}
}
posted @ 2015-06-06 20:58 Enic 阅读(586) | 评论 (0)编辑 收藏

在sqlserver 下想复制一张表的,想到oracle下直接create table xxx as select * from ....即可。
但是结果却是错误的,baidu一下发现。
sqlserver的语法是 : select * into tablenew from tableold



CREATE TABLE #TemTable AS SELECT * FROM PlatformCoinExchangeRecord;
SELECT * INTO #TemTable FROM PlatformCoinExchangeRecord;
SELECT * FROM #TemTable;
DROP TABLE #TemTable;


CREATE TABLE #TemTable 
(TotalOnlineDuration bigint, 
ByPlayDuration int, 
TotalPlayTimes int, 
Task30 int, 
Task60 int, 
Task120 int);
INSERT INTO #TemTable exec NET_PW_GetPlayDurationTask 539;
SELECT * from #TemTable;
DROP TABLE #TemTable;
临时表可能创建后可能应为其他原因导致没有执行到drop,这样下次执行的时候临时表还存在,所以创建临时表以后最好会是做异常处理在catch中强制销毁。
CONTINUE HANDLE mysql可以用这个东西

 CREATE TEMPORARY table IF NOT EXISTS alarmLeveltb
 (    devID bigint not null,
      alarmLevel bigint not null
 );

truncate TABLE alarmLeveltb;--清空表中的数据

如果不存在某个表就创建,mysql写法

IF objectproperty(object_id(@DbTableFileName),'IsUserTable') IS NOT NULL
   PRINT 'EXISTS '
ELSE
   PRINT 'NOT EXISTS '


貌似没有找到直接创建的办法,所以要约定好结果集
posted @ 2015-05-26 11:37 Enic 阅读(184) | 评论 (0)编辑 收藏

在同一个sql语句中写不同条件的Count数量
select sum(case when Experience >= 218706 then 1 else 0 end) as '[25,+',
  sum(case when Experience >= 49065 and Experience < 218706 then 1 else 0 end) as '[20,25)',
       sum(case when Experience >= 11773 and Experience < 49065 then 1 else 0 end) as '[15,20)',
  sum(case when Experience >= 2171 and Experience < 11773 then 1 else 0 end) as '[10,15)'
from QPAccountsDB.dbo.AccountsInfo where IsAndroid = 0;

http://blog.csdn.net/wangziling100/article/details/7598873

posted @ 2015-05-20 15:49 Enic 阅读(213) | 评论 (0)编辑 收藏

仅列出标题
共22页: 1 2 3 4 5 6 7 8 9 Last