| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1601 人关注过本帖
标题:请看看静态库Dll问题
只看楼主 加入收藏
rxgmoral
Rank: 1
等 级:新手上路
帖 子:45
专家分:0
注 册:2006-1-18
收藏
 问题点数:0 回复次数:4 
请看看静态库Dll问题

请看看静态库Dll问题
我写了一个静态库的Dll,并继承了CListCtrl
<<<<<<<<<CmControl.h>>>>>>>>
#pragma once
#ifndef Define_Dll
#define Define_Dll __declspec(dllimport)
#endif
class Define_Dll ListCtrl:public CListCtrl
{
public:
void rxgmoral();
};
<<<<<<<<<<CmControl.Cpp>>>>>>>>>>>
#define Define_Dll __declspec(dllexport)
#include "stdafx.h"
#include "CmControl.h"

void ListCtrl::rxgmoral()
{
AfxMessageBox(_T("yyyyy"));
}

************Test应用程序调用*******************
#include "CmControl.h"
#pragma comment(lib,"Share.lib")
.......................
ListCtrl asd;

报错如下:
Compiling...
TestDlg.cpp
e:\备份程序库\studio\test\test\cmcontrol.h(6) : warning C4275: non dll-interface class 'CListCtrl' used as base for dll-interface class 'ListCtrl'
d:\microsoft visual studio\vc\atlmfc\include\afxcmn.h(248) : see declaration of 'CListCtrl'
e:\备份程序库\studio\test\test\cmcontrol.h(5) : see declaration of 'ListCtrl'
Generating Code...
Compiling...
Test.cpp
e:\备份程序库\studio\test\test\cmcontrol.h(6) : warning C4275: non dll-interface class 'CListCtrl' used as base for dll-interface class 'ListCtrl'
d:\microsoft visual studio\vc\atlmfc\include\afxcmn.h(248) : see declaration of 'CListCtrl'
e:\备份程序库\studio\test\test\cmcontrol.h(5) : see declaration of 'ListCtrl'
Generating Code...
Linking...
Test.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: virtual __thiscall ListCtrl::~ListCtrl(void)" (__imp_??1ListCtrl@@UAE@XZ) referenced in function "public: virtual __thiscall CTestDlg::~CTestDlg(void)" (??1CTestDlg@@UAE@XZ)
TestDlg.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) public: virtual __thiscall ListCtrl::~ListCtrl(void)" (__imp_??1ListCtrl@@UAE@XZ)
TestDlg.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: __thiscall ListCtrl::ListCtrl(void)" (__imp_??0ListCtrl@@QAE@XZ) referenced in function "public: __thiscall CTestDlg::CTestDlg(class CWnd *)" (??0CTestDlg@@QAE@PAVCWnd@@@Z)
E:\备份程序库\Studio\Test\Debug\Test.exe : fatal error LNK1120: 2 unresolved externals
Build log was saved at "file://e:\备份程序库\Studio\Test\Test\Debug\BuildLog.htm"

我的"鸟"文不好,请问错那了
谢谢:)

搜索更多相关主题的帖子: Dll 静态 
2006-01-19 10:09
冰镇柠檬汁儿
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:北京
等 级:版主
威 望:120
帖 子:8078
专家分:6657
注 册:2005-11-7
收藏
得分:0 

wdscxsj 一定懂这个,我还没学过dll,你在http://www.programfan.com/club/showtxt.asp?id=137683
上发的帖子我会常去看的。
该学的东西太多了。


本来无一物,何处惹尘埃
It is empty at all here, Why pm 2.5 is so TMD high!
2006-01-19 16:23
冰镇柠檬汁儿
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:北京
等 级:版主
威 望:120
帖 子:8078
专家分:6657
注 册:2005-11-7
收藏
得分:0 
还请你多给我讲讲有关的知识吧,我没找到相关的材料。

本来无一物,何处惹尘埃
It is empty at all here, Why pm 2.5 is so TMD high!
2006-01-19 16:25
rxgmoral
Rank: 1
等 级:新手上路
帖 子:45
专家分:0
注 册:2006-1-18
收藏
得分:0 
一、DLL的不同类型
使用MFC可以生成两种类型的DLL:MFC扩展DLL和常规DLL。常规DLL有可以分为动态连接和静态连接。Visual C++还可以生成WIN32 DLL,但不是这里讨论的主要对象。
1、MFC扩展DLL
每个DLL都有某种类型的接口:变量、指针、函数、客户程序访问的类。它们的作用是让客户程序使用DLL,MFC扩展DLL可以有C++的接口。也就是它可以导出C++类给客户端。导出的函数可以使用C++/MFC数据类型做参数或返回值,导出一个类时客户端能创建类对象或者派生这个类。同时,在DLL中也可以使用DLL和MFC。
Visual C++使用的MFC类库也是保存在一个DLL中,MFC扩展DLL动态连接到MFC代码库的DLL,客户程序也必须要动态连接到MFC代码库的DLL。(这里谈到的两个DLL,一个是我们自己编写的DLL,一个装MFC类库的DLL)现在MFC代码库的DLL也存在多个版本,客户程序和扩展DLL都必须使用相同版本的MFC代码DLL。所以为了让MFC扩展DLL能很好的工作,扩展DLL和客户程序都必须动态连接到MFC代码库DLL。而这个DLL必须在客户程序运行的计算机上。
2、常规DLL
使用MFC扩展DLL的一个问题就是DLL仅能和MFC客户程序一起工作,如果需要一个使用更广泛的DLL,最好采用常规DLL,因为它不受MFC的某些限制。常规DLL也有缺点:它不能和客户程序发送指针或MFC派生类和对象的引用。一句话就是常规DLL和客户程序的接口不能使用MFC,但在DLL和客户程序的内部还是可以使用MFC。
当在常规DLL的内部使用MFC代码库的DLL时,可以是动态连接/静态连接。如果是动态连接,也就是常规DLL需要的MFC代码没有构建到DLL中,这种情况有点和扩展DLL类似,在DLL运行的计算机上必须要MFC代码库的DLL。如果是静态连接,常规DLL里面已经包含了需要的MFC代码,这样DLL的体积将比较大,但它可以在没有MFC代码库DLL的计算机上正常运行。

二、建立DLL
利用Visual C++提供的向导功能可以很容易建立一个不完成任何实质任务的DLL,这里就不多讲了,主要的任务是如何给DLL添加功能,以及在客户程序中利用这个DLL
1、导出类
用向导建立好框架后,就可以添加需要导出类的.cpp .h文件到DLL中来,或者用向导创建C++ Herder File/C++ Source File。为了能导出这个类,在类声明的时候要加“_declspec(dllexport)”,如:
class _declspec(dllexport) CMyClass
{
...//声明
}
如果创建的MFC扩展DLL,可以使用宏:AFX_EXT_CLASS:
class AFX_EXT_CLASS CMyClass
{
...//声明
}
这样导出类的方法是最简单的,也可以采用.def文件导出,这里暂不详谈。
2、导出变量、常量、对象
很多时候不需要导出一个类,可以让DLL导出一个变量、常量、对象,导出它们只需要进行简单的声明:_declspec(dllexport) int MyInt;
_declspec(dllexport) extern const COLORREF MyColor=RGB(0,0,0);
_declspec(dllexport) CRect rect(10,10,20,20);
要导出一个常量时必须使用关键字extern,否则会发生连接错误。
注意:如果客户程序识别这个类而且有自己的头文件,则只能导出一个类对象。如果在DLL中创建一个类,客户程序不使用头文件就无法识别这个类。
当导出一个对象或者变量时,载入DLL的每个客户程序都有一个自己的拷贝。也就是如果两个程序使用的是同一个DLL,一个应用程序所做的修改不会影响另一个应用程序。
我们在导出的时候只能导出DLL中的全局变量或对象,而不能导出局部的变量和对象,因为它们过了作用域也就不存在了,那样DLL就不能正常工作。如:
MyFunction()
{
_declspec(dllexport) int MyInt;
_declspec(dllexport) CMyClass object;
}
3、导出函数
导出函数和导出变量/对象类似,只要把_declspec(dllexport)加到函数原型开始的位置:
_declspec(dllexport) int MyFunction(int);
如果是常规DLL,它将和C写的程序使用,声明方式如下:
extern "c" _declspec(dllexport) int MyFunction(int);
实现:
extern "c" _declspec(dllexport) int MyFunction(int x)
{
...//操作
}
如果创建的是动态连接到MFC代码库DLL的常规DLL,则必须插入AFX_MANAGE_STATE作为导出函数的首行,因此定义如下:
extern "c" _declspec(dllexport) int MyFunction(int x)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
...//操作
}
有时候为了安全起见,在每个常规DLL里都加上,也不会有任何问题,只是在静态连接的时候这个宏无效而已。这是导出函数的方法,记住只有MFC扩展DLL才能让参数和返回值使用MFC的数据类型。
4、导出指针
导出指针的方式如下:
_declspec(dllexport) int *pint;
_declspec(dllexport) CMyClass object = new CMyClass;
如果声明的时候同时初始化了指针,就需要找到合适的地方类释放指针。在扩展DLL中有个函数DllMain()。(注意函数名中的两个l要是小写字母),可以在这个函数中处理指针:
# include "MyClass.h"
_declspec(dllexport) CMyClass *pobject = new CMyClass;
DllMain(HINSTANCE hInstance,DWORD dwReason,LPVOID lpReserved)
{
if(dwReason == DLL_PROCESS_ATTACH)
{
.....//
}
else if(dwReason == DLL_PROCESS_DETACH)
{
delete pobject;
}
}
常规DLL有一个从CWinApp派生的类对象处理DLL的开和关,可以使用类向导添加InitInstance/ExitInstance函数。
int CMyDllApp::ExitInstance()
{
delete pobject;
return CWinApp::ExitInstance();
}

三、在客户程序中使用DLL
编译一个DLL时将创建两个文件.dll文件和.lib文件。首先将这两个文件复制到客户程序项目的文件夹里,这里需要注意DLL和客户程序的版本问题,尽量使用相同的版本,都使用RELEASE或者都是DEBUG版本。
接着就需要在客户程序中设置LIB文件,打开Project Settings--->Link--->Object/library Modules中输入LIB的文件名和路径。如:Debug/SampleDll.lib。除了DLL和LIB文件外,客户程序需要针对导出类、函数、对象和变量的头文件,现在进行导入添加的关键字就是:_declspec(dllimport),如:
_declspec(dllimport) int MyFunction(int);
_declspec(dllimport) int MyInt;
_declspec(dllimport) CMyClass object;
extern "C" _declspec(dllimport) int MyFunction(int);
在有的时候为了导入类,要把相应类的头文件添加到客户程序中,不同的是要修改类声明的标志:
class _declspec(dllimport) CMyClass,如果创建的是扩展DLL,两个位置都是:
class AFX_EXT_CLASS CMyClass。

2006-01-19 17:51
冰镇柠檬汁儿
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:北京
等 级:版主
威 望:120
帖 子:8078
专家分:6657
注 册:2005-11-7
收藏
得分:0 
,自己找的,没时间看啊,我再研究吧

本来无一物,何处惹尘埃
It is empty at all here, Why pm 2.5 is so TMD high!
2006-01-20 09:02
快速回复:请看看静态库Dll问题
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.015501 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved