当前位置: 技术问答>linux和unix
头疼了N天了,求高人指点,linux下如何编写C++共享库?
来源: 互联网 发布时间:2016-02-26
本文导语: 由于考虑到以后代码的后期改动,本人想建立一个共享库mylib.so,用来给我的游戏算积分。代码如下: //gamescore.cpp #include #include "user.h" int GameScore(CUser *pstUserInfo, int iRoadID) { if(pstUserInfo==NULL) { printf("%s:%d->u...
由于考虑到以后代码的后期改动,本人想建立一个共享库mylib.so,用来给我的游戏算积分。代码如下:
//gamescore.cpp
#include
#include "user.h"
int GameScore(CUser *pstUserInfo, int iRoadID)
{
if(pstUserInfo==NULL)
{
printf("%s:%d->user info is nulln",__FILE__,__LINE__);
return -1;
}
pstUserInfo->m_stBaseInfo.m_dwExperience=10;
pstUserInfo->m_stBaseInfo.m_dwScore=11;
return 0;
}
以上代码中用到了C++的一个类CUser,传给积分函数用来修改积分。
用g++ -shared -fPIC -o gamescore.so -g gamescore.cpp
可以生成共享库gamescore.so。但是在如下的动态库调用主程序中,出现了问题(编译没问题,运行时出问题,找不到symbol)
//game.cpp
#include
#include
#include
#include
#include
#define SHARED /* 定义宏,确认共享,以便引用动态函数 */
#include "gamedll.h"
#define SOFILE "./gamescore.so" /* 指定动态链接库名称 */
void dll_init()
{
void *dp;
char *error;
dp=dlopen(SOFILE,RTLD_LAZY);
if(dp == NULL)
{
fprintf (stderr, "%sn", dlerror());
exit(0);
}
GameScore =(int (*)(CUser*, int))dlsym(dp,"GameScore");
error=dlerror(); /* 检测错误 */
if (error) /* 若出错则退出 */
{
perror("dlsym GameScore errorn");
printf("Error: %s",error);
exit(1);
}
}
main()
{
CUser *pstUser= new CUser;
dll_init();
GameScore(pstUser,0);
printf("pstUser->m_dwExperience= %d,pstUser->loser_point = %dn",pstUser->m_stBaseInfo.m_dwExperience,
pstUser->m_stBaseInfo.m_dwScore);
delete pstUser;
}
//gamedll.h如下:********************************
#ifndef _GAMEDLL_H_
#define _GAMEDLL_H_
#include "user.h"
#ifdef SHARED
int (*GameScore)(CUser *pstUserInfo, int iRoadID);
#else
int GameScore(CUser *pstUserInfo, int iRoadID);
#endif
#endif
说明:在redhat linux我的代码编译都没有问题(如果各位有的话,可能是我贴代码的时候有笔误),能生产gamescore.so,主程序也能通过!(用g++ -rdynamic -s -ld选项正确编译),但是在运行后:
[cjp@gameserver1 gamescore]$ ./game
dlsym GameScore error
: Success
Error: ./gamescore.so: undefined symbol: gamescore[cjp@gameserver1 gamescore]$
找不到so里面的symbol????!!!
我是照着网上流行一个用c语言来实现共享库的例子改造的!gcc下,按他的例子没问题,该成g++以后问题就一样了。
后来,我查了一些资料,说要加入:
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
来实现,但是像我这种应用,我非得要传入一个C++的类指针(或者说我一定要用C++来实现共享库),我该怎么办呢?
请高手不吝赐教!给分100,不要嫌少!关键教导我怎样做C++共享库,我将终身收益!感激不尽!
//gamescore.cpp
#include
#include "user.h"
int GameScore(CUser *pstUserInfo, int iRoadID)
{
if(pstUserInfo==NULL)
{
printf("%s:%d->user info is nulln",__FILE__,__LINE__);
return -1;
}
pstUserInfo->m_stBaseInfo.m_dwExperience=10;
pstUserInfo->m_stBaseInfo.m_dwScore=11;
return 0;
}
以上代码中用到了C++的一个类CUser,传给积分函数用来修改积分。
用g++ -shared -fPIC -o gamescore.so -g gamescore.cpp
可以生成共享库gamescore.so。但是在如下的动态库调用主程序中,出现了问题(编译没问题,运行时出问题,找不到symbol)
//game.cpp
#include
#include
#include
#include
#include
#define SHARED /* 定义宏,确认共享,以便引用动态函数 */
#include "gamedll.h"
#define SOFILE "./gamescore.so" /* 指定动态链接库名称 */
void dll_init()
{
void *dp;
char *error;
dp=dlopen(SOFILE,RTLD_LAZY);
if(dp == NULL)
{
fprintf (stderr, "%sn", dlerror());
exit(0);
}
GameScore =(int (*)(CUser*, int))dlsym(dp,"GameScore");
error=dlerror(); /* 检测错误 */
if (error) /* 若出错则退出 */
{
perror("dlsym GameScore errorn");
printf("Error: %s",error);
exit(1);
}
}
main()
{
CUser *pstUser= new CUser;
dll_init();
GameScore(pstUser,0);
printf("pstUser->m_dwExperience= %d,pstUser->loser_point = %dn",pstUser->m_stBaseInfo.m_dwExperience,
pstUser->m_stBaseInfo.m_dwScore);
delete pstUser;
}
//gamedll.h如下:********************************
#ifndef _GAMEDLL_H_
#define _GAMEDLL_H_
#include "user.h"
#ifdef SHARED
int (*GameScore)(CUser *pstUserInfo, int iRoadID);
#else
int GameScore(CUser *pstUserInfo, int iRoadID);
#endif
#endif
说明:在redhat linux我的代码编译都没有问题(如果各位有的话,可能是我贴代码的时候有笔误),能生产gamescore.so,主程序也能通过!(用g++ -rdynamic -s -ld选项正确编译),但是在运行后:
[cjp@gameserver1 gamescore]$ ./game
dlsym GameScore error
: Success
Error: ./gamescore.so: undefined symbol: gamescore[cjp@gameserver1 gamescore]$
找不到so里面的symbol????!!!
我是照着网上流行一个用c语言来实现共享库的例子改造的!gcc下,按他的例子没问题,该成g++以后问题就一样了。
后来,我查了一些资料,说要加入:
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
来实现,但是像我这种应用,我非得要传入一个C++的类指针(或者说我一定要用C++来实现共享库),我该怎么办呢?
请高手不吝赐教!给分100,不要嫌少!关键教导我怎样做C++共享库,我将终身收益!感激不尽!
|
根据你的代码,我改了一个地方,可以运行通过了。
关键在于在mylib.c里加上
extern "C" int GameScore(CUser*, int);
这样生成so的时候才会生成C风格的symbol,否则就会生成C++的类似_Z9GameScoreP5CUseri这样的名字。
关键在于在mylib.c里加上
extern "C" int GameScore(CUser*, int);
这样生成so的时候才会生成C风格的symbol,否则就会生成C++的类似_Z9GameScoreP5CUseri这样的名字。