类里面的线程怎么使用类里面的static变量??

linyilong3 2011-05-31 09:40:25
我昨天把原来用C做的东西封装进了类里面,用了线程,但是在类里面用线程要把函数定义为static,但是函数定义为static的话又要把线程的函数要用到的东西定义为static,结果链接的时候出错了,怎么办??,错误如下

1>CAudioChat.obj : error LNK2001: 无法解析的外部符号 "private: static bool CAudioChat::IsSpeakFinsh" (?IsSpeakFinsh@CAudioChat@@0_NA)
1>CAudioChat.obj : error LNK2001: 无法解析的外部符号 "private: static bool CAudioChat::IsTimeOut" (?IsTimeOut@CAudioChat@@0_NA)
1>CAudioChat.obj : error LNK2001: 无法解析的外部符号 "private: static struct wavehdr_tag CAudioChat::InWaveHdr" (?InWaveHdr@CAudioChat@@0Uwavehdr_tag@@A)
1>CAudioChat.obj : error LNK2001: 无法解析的外部符号 "private: static char (* CAudioChat::HostIP)[28]" (?HostIP@CAudioChat@@0PAY0BM@DA)
1>CAudioChat.obj : error LNK2001: 无法解析的外部符号 "private: static unsigned int CAudioChat::sSend" (?sSend@CAudioChat@@0IA)
1>CAudioChat.obj : error LNK2001: 无法解析的外部符号 "private: static struct sockaddr_in CAudioChat::sin_Send" (?sin_Send@CAudioChat@@0Usockaddr_in@@A)
1>CAudioChat.obj : error LNK2001: 无法解析的外部符号 "private: static struct protocol CAudioChat::SendData" (?SendData@CAudioChat@@0Uprotocol@@A)
1>CAudioChat.obj : error LNK2001: 无法解析的外部符号 "private: static struct HWAVEOUT__ * CAudioChat::hWaveOut" (?hWaveOut@CAudioChat@@0PAUHWAVEOUT__@@A)
1>CAudioChat.obj : error LNK2001: 无法解析的外部符号 "private: static struct wavehdr_tag CAudioChat::OutWaveHdr" (?OutWaveHdr@CAudioChat@@0Uwavehdr_tag@@A)
1>CAudioChat.obj : error LNK2001: 无法解析的外部符号 "private: static unsigned int CAudioChat::sRecv" (?sRecv@CAudioChat@@0IA)
1>CAudioChat.obj : error LNK2001: 无法解析的外部符号 "private: static struct protocol CAudioChat::RecvData" (?RecvData@CAudioChat@@0Uprotocol@@A)
1>CAudioChat.obj : error LNK2001: 无法解析的外部符号 "private: static struct sockaddr_in CAudioChat::sin_Recv" (?sin_Recv@CAudioChat@@0Usockaddr_in@@A)
1>CAudioChat.obj : error LNK2001: 无法解析的外部符号 "private: static struct sockaddr_in CAudioChat::sin_server" (?sin_server@CAudioChat@@0Usockaddr_in@@A)
1>CAudioChat.obj : error LNK2001: 无法解析的外部符号 "private: static unsigned int CAudioChat::sServer" (?sServer@CAudioChat@@0IA)
1>CAudioChat.obj : error LNK2001: 无法解析的外部符号 "private: static struct HWAVEIN__ * CAudioChat::hWaveIn" (?hWaveIn@CAudioChat@@0PAUHWAVEIN__@@A)
1>CAudioChat.obj : error LNK2001: 无法解析的外部符号 "private: static unsigned long CAudioChat::OutAudioThreadID" (?OutAudioThreadID@CAudioChat@@0KA)
1>CAudioChat.obj : error LNK2001: 无法解析的外部符号 "private: static unsigned long CAudioChat::CurrentChannel" (?CurrentChannel@CAudioChat@@0KA)
1>CAudioChat.obj : error LNK2001: 无法解析的外部符号 "private: static class std::queue<struct protocol,class std::deque<struct protocol,class std::allocator<struct protocol> > > CAudioChat::RecvQueue" (?RecvQueue@CAudioChat@@0V?$queue@Uprotocol@@V?$deque@Uprotocol@@V?$allocator@Uprotocol@@@std@@@std@@@std@@A)
1>E:\lin\Sound\CAudioChat\Debug\CAudioChat.exe : fatal error LNK1120: 18 个无法解析的外部命令
...全文
155 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
linyilong3 2011-05-31
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 qq120848369 的回复:]

额,举个简单例子,照做就可以了.

头文件:
class C
{
private:
static sockaddr_in sockAddr;
};

源文件:#include "头文件"
sockaddr_in C::sockAddr=0;

这样就可以了,你有初始值得话就写上(上边红色部分),没有就不用写,有木有都要在外边写一次.
[/Quote]

哦,谢谢了,我用了前面传this的方法
碎碎念 2011-05-31
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 linyilong3 的回复:]

引用 11 楼 ljt3969636 的回复:

把静态成员的“定义”也加到“另一个文”件里
DWORD CAudioChat::OutAudioThreadID=0;//以他为例这是static的定义初始化~

那结构体怎么定义??类似sockaddr_in这种
[/Quote]
初始化为0
memset(&(CAudioChat::sin_Recv),0,sizeof(sockaddr_in));
qq120848369 2011-05-31
  • 打赏
  • 举报
回复
额,举个简单例子,照做就可以了.

头文件:
class C
{
private:
static sockaddr_in sockAddr;
};

源文件:#include "头文件"
sockaddr_in C::sockAddr=0;

这样就可以了,你有初始值得话就写上(上边红色部分),没有就不用写,有木有都要在外边写一次.
dengqibin 2011-05-31
  • 打赏
  • 举报
回复

DWORD CALLBACK CAudioChat::RecvThread(LPVOID lpParameter)
{
CAudioChat *p=(CAudioChat *)lpParameter;
if(p==NULL) return -1;
while(true)
{
p->RecvAudio();
if(!p->IsMySelfAudio())
p->RecvQueue.push(RecvData);
}
return 0;
}

void CAudioChat::CreateOutThread()
{
hRecvThread=CreateThread(NULL,0,RecvThread,this,0,NULL);
}

类似这个样子
linyilong3 2011-05-31
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 dengqibin 的回复:]

线程函数用static 然后在线程那把this传进去,这样就不用那么多的static了吧
[/Quote]
看不懂,我对C++不是很熟,当然this这种东西还是懂的
linyilong3 2011-05-31
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 ljt3969636 的回复:]

把静态成员的“定义”也加到“另一个文”件里
DWORD CAudioChat::OutAudioThreadID=0;//以他为例这是static的定义初始化~
[/Quote]
那结构体怎么定义??类似sockaddr_in这种
dengqibin 2011-05-31
  • 打赏
  • 举报
回复
线程函数用static 然后在线程那把this传进去,这样就不用那么多的static了吧
linyilong3 2011-05-31
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 zhaojingbupt11 的回复:]

静态成员函数内,不能直接访问类的成员。所以不能直接访问非静态成员,不用改成静态的,只需要一个对象实例来访问。可以建立一个全局的对象实例m_CAudioChat,在线程函数内用m_CAudioChat.XX来访问。
[/Quote]
什么意思??
LBJMD 2011-05-31
  • 打赏
  • 举报
回复
为什么不把线程函数定义成全局函数,这样就可以避免使用静态变量了,用全局变量就可以替代了
zhaojingbupt11 2011-05-31
  • 打赏
  • 举报
回复
另外,你在类里面改了static,那是声明不是定义。static变量要在cpp里面定义一次XXX XXX::XXX = XXX 。
XXX是类型
zhaojingbupt11 2011-05-31
  • 打赏
  • 举报
回复
静态成员函数内,不能直接访问类的成员。所以不能直接访问非静态成员,不用改成静态的,只需要一个对象实例来访问。可以建立一个全局的对象实例m_CAudioChat,在线程函数内用m_CAudioChat.XX来访问。
ljt3969636 2011-05-31
  • 打赏
  • 举报
回复
把静态成员的“定义”也加到“另一个文”件里
DWORD CAudioChat::OutAudioThreadID=0;//以他为例这是static的定义初始化~
linyilong3 2011-05-31
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 aozhi 的回复:]

还是看看CAudioChat.cpp文件吧。
标识符是怎么用的?怎么都是外部标识符?奇怪。
[/Quote]

4L是头文件,7L是CPP的文件,在外部初始化的话,那结构体那些怎么办?还有外部初始化是在编译器的时候初始化还是什么?
aozhi 2011-05-31
  • 打赏
  • 举报
回复
把两个文件合起来行吗?
aozhi 2011-05-31
  • 打赏
  • 举报
回复
还是看看CAudioChat.cpp文件吧。
标识符是怎么用的?怎么都是外部标识符?奇怪。
linyilong3 2011-05-31
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 luciferisnotsatan 的回复:]

贴出的代码,都是只有声明,没有定义。你的代码里都做定义了?函数和变量都需要定义下。
[/Quote]

在另外一个文件定义了,另外一个文件300行

#include "CAudioChat.h"
#include <Windows.h>
#include <MMSystem.h>
#include <cstring>

CAudioChat::CAudioChat()
{
InitSockData();
ConnectToServer();
InitWaveOut();
InitWaveIn();
IsTimeOut=false;
IsSpeakFinsh=false;
GetHostIP();
CreateBroadRecv();
}
CAudioChat::~CAudioChat()
{
delete []InWaveHdr.lpData;
}
void CAudioChat::TransLastError(DWORD ErrCode)
{
LPVOID lpMsgBuf;
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | \
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,\
NULL,ErrCode,0,(LPSTR)&lpMsgBuf,0,NULL);
cout<<lpMsgBuf<<endl;
}
void CAudioChat::InitSockData()
{
WSADATA wsaData;
WORD sockVersion=MAKEWORD(2,0);
WSAStartup(sockVersion,&wsaData);
}

void CAudioChat::GetHostIP()
{
char HostName[56];
gethostname(HostName,sizeof(HostName)*sizeof(char));

for(int i=0;i<5;i++)
{
ZeroMemory(HostIP[i],sizeof(HostIP[i]));
}
struct hostent *HostInfo;
int i=0;
if((HostInfo=gethostbyname(HostName)) != NULL)
{
while(HostInfo->h_addr_list[i])
{
strcpy_s(HostIP[i],inet_ntoa(*(struct in_addr*)HostInfo->h_addr_list[i]));
i++;
}
}
}

DWORD CAudioChat::SendAudio()
{
strncpy_s(SendData.Data,InWaveHdr.lpData,InWaveHdr.dwBufferLength-200);
SendData.dwBufferLenght=InWaveHdr.dwBufferLength;
DWORD nSend=0;
nSend=sendto(sSend,(char *)&SendData,sizeof(SendData),0,(sockaddr *)&sin_Send,sizeof(sin_Send));

return nSend;
}

void CAudioChat::PlayAudio()
{
waveOutPrepareHeader(hWaveOut,&OutWaveHdr,sizeof(WAVEHDR));
waveOutPause(hWaveOut);

waveOutWrite(hWaveOut,&OutWaveHdr,sizeof(WAVEHDR));
waveOutRestart(hWaveOut);

MSG msg;
while(true)
{
if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
if(msg.message==WM_QUIT)
break;
}
else
{
WaitMessage();
}
}
}
DWORD CAudioChat::RecvAudio()
{
DWORD nRecv;
int nLen=sizeof(sin_Recv);
nRecv=recvfrom(sRecv,(char *)&RecvData,sizeof(struct protocol),0,(sockaddr *)&sin_Recv,&nLen);
return nRecv;
}
int CAudioChat::ConnectToServer(const char *Address,const int Port)
{
sServer=socket(AF_INET,SOCK_STREAM,0);
sin_server.sin_family=AF_INET;
sin_server.sin_port=htons(Port);
sin_server.sin_addr.S_un.S_addr=inet_addr(Address);

int ret=connect(sServer,(sockaddr*)&sin_server,sizeof(struct sockaddr_in));
if(ret != -1)
SendUserInfo();
else
TransLastError(WSAGetLastError());
return ret;
}

void CAudioChat::SendUserInfo(const char *name,const int priority)
{
send(sServer,name,strlen(name),0);
send(sServer,(char *)&priority,sizeof(int),0);
}

int CAudioChat::CreateBroadSend()
{
sSend=socket(AF_INET,SOCK_DGRAM,0);
BOOL bBroadCast=TRUE;
sin_Send.sin_family=AF_INET;
sin_Send.sin_addr.S_un.S_addr=INADDR_BROADCAST;
sin_Send.sin_port=htons(SERVER_PORT);

setsockopt(sSend,SOL_SOCKET,SO_BROADCAST,(char *)&bBroadCast,sizeof(BOOL));
return 0;
}

int CAudioChat::CreateBroadRecv()
{
sRecv=socket(AF_INET,SOCK_DGRAM,0);
sin_Recv.sin_family=AF_INET;
sin_Recv.sin_addr.S_un.S_addr=INADDR_ANY;
sin_Recv.sin_port=htons(SERVER_PORT);

return (bind(sRecv,(sockaddr *)&sin_Recv,sizeof(sin_Recv))==SOCKET_ERROR);
}

void CAudioChat::InitWaveFormat()
{
wfx.wFormatTag=WAVE_FORMAT_PCM;
wfx.nChannels=1;
wfx.nSamplesPerSec=5000;
wfx.nAvgBytesPerSec=5000;
wfx.nBlockAlign=1;
wfx.wBitsPerSample=8;
wfx.cbSize=0;
}

void CAudioChat::InitInWaveHdr()
{
InWaveHdr.lpData=new char[ALLOC_BUF];
InWaveHdr.dwBufferLength=ALLOC_BUF*sizeof(char);
InWaveHdr.dwBytesRecorded=0;
InWaveHdr.dwUser=0;
InWaveHdr.dwFlags=0;
InWaveHdr.dwLoops=0;
}

void CAudioChat::InitOutWaveHdr()
{
OutWaveHdr.lpData=NULL;
OutWaveHdr.dwBufferLength=0;
OutWaveHdr.dwBytesRecorded=0;
OutWaveHdr.dwUser=0;
OutWaveHdr.dwFlags=0;
OutWaveHdr.dwLoops=0;
}


void CAudioChat::InitWaveIn()
{
InitWaveFormat();
InitInWaveHdr();
waveInOpen(&hWaveIn,WAVE_MAPPER,&wfx,NULL,0L,CALLBACK_NULL);
}

void CAudioChat::WaveInBuf()
{
waveInPrepareHeader(hWaveIn,&InWaveHdr,sizeof(WAVEHDR));
waveInAddBuffer(hWaveIn,&InWaveHdr,sizeof(WAVEHDR));
}

void CAudioChat::BeginRecord(const int nTime)
{
MMTIME mmt;
WaveInBuf();
waveInStart(hWaveIn);
Sleep(nTime);
waveInGetPosition(hWaveIn,&mmt,sizeof(MMTIME));
waveInReset(hWaveIn);
InWaveHdr.dwBufferLength=mmt.u.cb;
waveInUnprepareHeader(hWaveIn,&InWaveHdr,sizeof(WAVEHDR));
}


void CAudioChat::waveOutProc(HWAVEOUT hwo,UINT uMsg,DWORD dwInstance,DWORD dwParam1,DWORD dwParam2)
{
switch(uMsg)
{
case WOM_DONE:
cout<<"Done"<<endl;
PostThreadMessage(OutAudioThreadID,WM_QUIT,0,0);
break;
case WOM_OPEN:
break;
case WOM_CLOSE:
break;
default:
break;
}
}

bool CAudioChat::IsPlay()
{
return (RecvQueue.front().Channel==CurrentChannel);
}
void CAudioChat::InitWaveOut()
{
InitWaveFormat();
InitOutWaveHdr();
waveOutOpen(&hWaveOut,WAVE_MAPPER,&wfx,(DWORD)waveOutProc,0,CALLBACK_FUNCTION);
}

bool CAudioChat::IsMySelfAudio()
{
int i=0;
while(HostIP[i][0] && i<5)
{
if(!strcmp(HostIP[i],inet_ntoa(sin_Recv.sin_addr)))
return true;
}
return false;
}

DWORD CALLBACK CAudioChat::OutAudioThread(LPVOID lpParameter)
{
OutAudioThreadID=GetCurrentThreadId();
bool isFirst=true;
while(true)
{
if(!RecvQueue.empty())
{
if(isFirst)
{
if(IsPlay())
{
OutWaveHdr.lpData=RecvQueue.front().Data;
OutWaveHdr.dwBufferLength=RecvQueue.front().dwBufferLenght;
PlayAudio();
}
}
isFirst=!isFirst;
RecvQueue.pop();
}
}
return 0;
}

DWORD CALLBACK CAudioChat::InAudioThread(LPVOID lpParameter)
{
while(true)
{
if(IsTimeOut || IsSpeakFinsh)
break;
BeginRecord();
SendData.dwBufferLenght=InWaveHdr.dwBufferLength;
strncpy_s(SendData.Data,InWaveHdr.lpData,InWaveHdr.dwBufferLength-200);
SendAudio();
}
return 0;
}

DWORD CALLBACK CAudioChat::RecvThread(LPVOID lpParameter)
{
while(true)
{
RecvAudio();
if(!IsMySelfAudio())
RecvQueue.push(RecvData);
}
return 0;
}

void CAudioChat::CreateOutThread()
{
hOutAudio=CreateThread(NULL,0,OutAudioThread,NULL,0,NULL);
hRecvThread=CreateThread(NULL,0,RecvThread,NULL,0,NULL);
}
ljt3969636 2011-05-31
  • 打赏
  • 举报
回复
class CAudioChat
{
public:
CAudioChat();
~CAudioChat();

/************************************************************************/
/* NetWork Public Function */
/************************************************************************/
static int CreateBroadSend();
static int CreateBroadRecv();
void CreateOutThread();
void CreateInThread();
static DWORD SendAudio();
static DWORD RecvAudio();
static void PlayAudio();
/************************************************************************/
/* Audio Function */
/************************************************************************/

static void BeginRecord(const int nTime=500);
static void waveOutProc(HWAVEOUT hwo,UINT uMsg,DWORD dwInstance,DWORD dwParam1,DWORD dwParam2);
private:
/************************************************************************/
/* NetWork Private Function */
/************************************************************************/
void InitSockData(void);
void GetHostIP();
int ConnectToServer(const char *Address="210.34.158.99",const int Port=SERVER_PORT);
void SendUserInfo(const char *name="NoName",const int priority=10);

/************************************************************************/
/* Audio Private Function */
/************************************************************************/

static DWORD CALLBACK OutAudioThread(LPVOID lpParameter);
static DWORD CALLBACK InAudioThread(LPVOID lpParameter);
static DWORD CALLBACK RecvThread(LPVOID lpParameter);
void InitWaveFormat();
void InitInWaveHdr();
void InitOutWaveHdr();
static bool IsPlay();
static bool IsMySelfAudio();
/************************************************************************/
/* In Audio Function */
/************************************************************************/
void InitWaveIn();
static void WaveInBuf();

/************************************************************************/
/* Out Audio Function */
/************************************************************************/
void InitWaveOut();

void TransLastError(DWORD ErrCode);


private:
static DWORD OutAudioThreadID;
static DWORD CurrentChannel;
static bool IsTimeOut;
static bool IsSpeakFinsh;
static queue<struct protocol> RecvQueue;
WAVEFORMATEX wfx;
static HWAVEIN hWaveIn;
static HWAVEOUT hWaveOut;

static WAVEHDR InWaveHdr;
static WAVEHDR OutWaveHdr;

static char HostIP[5][28];

static SOCKET sRecv;
static SOCKET sSend;
static SOCKET sServer;

static struct sockaddr_in sin_Recv;
static struct sockaddr_in sin_Send;
static struct sockaddr_in sin_server;

static struct protocol RecvData;
static struct protocol SendData;

HANDLE hOutAudio;
HANDLE hInAudio;
HANDLE hRecvThread;
};



DWORD CAudioChat::OutAudioThreadID=0;//以他为例这是static的定义初始化~
luciferisnotsatan 2011-05-31
  • 打赏
  • 举报
回复
贴出的代码,都是只有声明,没有定义。你的代码里都做定义了?函数和变量都需要定义下。
linyilong3 2011-05-31
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 qq120848369 的回复:]

static的东西除了要在类定义体内写一次以外,还要在类外初始化一次。
[/Quote]

那里面很多static变量的,在线程里面要用到的东西太多了,而且类似线程ID这种变量很难在外面初始化吧

下面是类的定义

class CAudioChat
{
public:
CAudioChat();
~CAudioChat();

/************************************************************************/
/* NetWork Public Function */
/************************************************************************/
static int CreateBroadSend();
static int CreateBroadRecv();
void CreateOutThread();
void CreateInThread();
static DWORD SendAudio();
static DWORD RecvAudio();
static void PlayAudio();
/************************************************************************/
/* Audio Function */
/************************************************************************/

static void BeginRecord(const int nTime=500);
static void waveOutProc(HWAVEOUT hwo,UINT uMsg,DWORD dwInstance,DWORD dwParam1,DWORD dwParam2);
private:
/************************************************************************/
/* NetWork Private Function */
/************************************************************************/
void InitSockData(void);
void GetHostIP();
int ConnectToServer(const char *Address="210.34.158.99",const int Port=SERVER_PORT);
void SendUserInfo(const char *name="NoName",const int priority=10);

/************************************************************************/
/* Audio Private Function */
/************************************************************************/

static DWORD CALLBACK OutAudioThread(LPVOID lpParameter);
static DWORD CALLBACK InAudioThread(LPVOID lpParameter);
static DWORD CALLBACK RecvThread(LPVOID lpParameter);
void InitWaveFormat();
void InitInWaveHdr();
void InitOutWaveHdr();
static bool IsPlay();
static bool IsMySelfAudio();
/************************************************************************/
/* In Audio Function */
/************************************************************************/
void InitWaveIn();
static void WaveInBuf();

/************************************************************************/
/* Out Audio Function */
/************************************************************************/
void InitWaveOut();

void TransLastError(DWORD ErrCode);


private:
static DWORD OutAudioThreadID;
static DWORD CurrentChannel;
static bool IsTimeOut;
static bool IsSpeakFinsh;
static queue<struct protocol> RecvQueue;
WAVEFORMATEX wfx;
static HWAVEIN hWaveIn;
static HWAVEOUT hWaveOut;

static WAVEHDR InWaveHdr;
static WAVEHDR OutWaveHdr;

static char HostIP[5][28];

static SOCKET sRecv;
static SOCKET sSend;
static SOCKET sServer;

static struct sockaddr_in sin_Recv;
static struct sockaddr_in sin_Send;
static struct sockaddr_in sin_server;

static struct protocol RecvData;
static struct protocol SendData;

HANDLE hOutAudio;
HANDLE hInAudio;
HANDLE hRecvThread;
};

qq120848369 2011-05-31
  • 打赏
  • 举报
回复
static的东西除了要在类定义体内写一次以外,还要在类外初始化一次。
加载更多回复(2)

64,654

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧