用vc2008链接库文件出现的错误

testing2007 2011-02-25 03:53:17
静态库文件:DebugUtility.lib
console.h

#if !defined(__CONSOLE_H_)
#define __CONSOLE_H_

#include <windows.h>

#define OUTPUT(msg) CConsole::GetInstance().Output(msg)

class CConsole
{
public:
// write output to console
void Output(LPCTSTR szOutput = NULL, ...);
public:
static CConsole& GetInstance();

private:
CConsole();

private:
// create the console
bool Create(LPCTSTR szTitle);
private:
HANDLE hConsole;
};

#endif


console.cpp


#include "stdafx.h"
#include "Console.h"

// macro for the Clear() function
#define ERR(bSuccess) { if(!bSuccess) return; }
// macro to check whether hConsole is valid
#define CHECK(hHandle) { if(hHandle == NULL) return; };

CConsole& CConsole::GetInstance()
{
static CConsole *_instance = new CConsole();
return *_instance;
}

CConsole::CConsole()
{
hConsole=NULL;
GetInstance().Create(__TEXT("console"));
}

bool CConsole::Create(LPCTSTR szTitle)
{
// Has console been already created?
if(hConsole != NULL)
return false;

// Allocate a new console for our app
if(!AllocConsole())
return false;

// Create the actual console
hConsole = CreateFile(__TEXT("CONOUT$"), GENERIC_WRITE|GENERIC_READ, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
if(hConsole == INVALID_HANDLE_VALUE)
return false;

if(SetConsoleMode(hConsole, ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT ) == 0)
return false;

// set the console title
if(szTitle != NULL)
SetConsoleTitle(szTitle);

return true;
}

void CConsole::Output(LPCTSTR szOutput, ...)
{
CHECK(hConsole);

DWORD dwWritten;
WCHAR out[256];
va_list va;

// if not parameter set, write a new line
if(szOutput == NULL)
wsprintfW(out,__TEXT("\n"));
// process arguments
else
{
va_start(va, szOutput);
wvsprintf(out, szOutput, va);
va_end(va);
}

// write to the console
WriteConsole(hConsole,out,wcslen(out),&dwWritten,0);
}


客户端:生成一个简单的windows应用程序,在winMain中插入.lib文件中的代码。在开发环境中链接了上面的DebugUtility.lib文件以及加入了相应的库文件目录。


#include "Console.h"

int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);

// TODO: 在此放置代码。
MSG msg;
HACCEL hAccelTable;

// 初始化全局字符串
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_MESSAGEQUEUE, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);

// OUTPUT(__TEXT("main"));
CConsole::GetInstance();//--》出现错误LKN2019


1>正在链接...
1>MessageQueue.obj : error LNK2019: 无法解析的外部符号 "public: static class CConsole & __cdecl CConsole::GetInstance(void)" (?GetInstance@CConsole@@SAAAV1@XZ),该符号在函数 _wWinMain@16 中被引用
1>D:\test\MessageQueue\Debug\MessageQueue.exe : fatal error LNK1120: 1 个无法解析的外部命令

使用dumpbin /exports /symbols /out:d:\out.txt 在导出的文件中找到这样一行:

00E 00000000 SECT3 notype () External | ?GetInstance@CConsole@@CAAAV1@XZ (private: static class CConsole & __cdecl CConsole::GetInstance(void))

为什么导出来的是private呢?这个很奇怪。我在lib文件明明写的是public啊,如果有高手不妨指教一下。谢谢!
...全文
115 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
mstlq 2011-02-25
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 testing2007 的回复:]
这样做就不会出现问题:
工程--》属性--》通用属性--》框架和引用,添加新应用。
但是如果你是通过如下方式就会报错:
工程--》配置属性--》链接器--》输入--》附加依赖项:加入lib文件名
工程--》配置属性--》链接器--》常规--》附加库目录:加入lib文件路径;
而且这两个不能同时使用,否则会出现.lib中的函数重定义的情况。
这两种方式有区别嘛?
[/Quote]

奇怪,我一直用第二种,没事啊……
testing2007 2011-02-25
  • 打赏
  • 举报
回复
在程序中有个地方写错了:GetInstance().Create(__TEXT("console"));
应该去掉GetInstance().
testing2007 2011-02-25
  • 打赏
  • 举报
回复
这样做就不会出现问题:
工程--》属性--》通用属性--》框架和引用,添加新应用。
但是如果你是通过如下方式就会报错:
工程--》配置属性--》链接器--》输入--》附加依赖项:加入lib文件名
工程--》配置属性--》链接器--》常规--》附加库目录:加入lib文件路径;
而且这两个不能同时使用,否则会出现.lib中的函数重定义的情况。
这两种方式有区别嘛?
mstlq 2011-02-25
  • 打赏
  • 举报
回复
请重新编译一下lib试试,注意.h的版本没错

64,654

社区成员

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

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