Dll导出静态成员问题?

farland 2004-06-14 11:18:37
class AFX_CLASS_EXPORT class1
{
protected:
static double m_Value;
public:
double& GetValue(){return m_Value;}// code 1
};

在class1.cpp中初始化
double class1::m_Value=0.0;
在有(code1)GetValue()时编译会出现“error LNK2001: unresolved external symbol "protected: static double class1::m_Value" (?nnn@class1@@2HA)”
请问如何解决这个问题
...全文
656 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
sevencat 2004-07-16
  • 打赏
  • 举报
回复
我的QQ:43791167
sevencat 2004-07-16
  • 打赏
  • 举报
回复
你要邮箱吗?我可以发一个给你。
这是我的DLL
#ifdef TESTDLL_EXPORTS
#define TESTDLL_API __declspec(dllexport)
#else
#define TESTDLL_API __declspec(dllimport)
#endif

// 此类是从 testdll.dll 导出的
class TESTDLL_API Ctestdll {
public:
Ctestdll(void);
static int xx;
};

// testdll.cpp : 定义 DLL 应用程序的入口点。
//

#include "stdafx.h"
#include "testdll.h"
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}

// 这是已导出类的构造函数。
// 有关类定义的信息,请参阅 testdll.h
Ctestdll::Ctestdll()
{
return;
}

int Ctestdll::xx=1;

这是我的EXE

// testexe.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "../testdll/testdll.h"

int _tmain(int argc, _TCHAR* argv[])
{
Ctestdll *pdll=new Ctestdll;
int x=pdll->xx;
printf("%d",x);
return 0;
}

#pragma comment(lib,"testdll")

环境:VC7.1
farland 2004-07-16
  • 打赏
  • 举报
回复
"绝对可以,而且我不用AFXEXT,我用的纯WI32"
请问sevencat(七猫) 兄:导出一般成员变量和静态成员变量在步骤上有什么不同?
sevencat 2004-07-09
  • 打赏
  • 举报
回复
绝对可以,而且我不用AFXEXT,我用的纯WI32
farland 2004-07-08
  • 打赏
  • 举报
回复
在一个国外网站上看到以下说明:
_declspec(dllexport) is trying to export the symbol erlStarted. A 'static' declaration gives the variable file scope - it CAN'T be exported. Your two declarations are in direct conflict, so it won't compile.
是不是说明,不能导出static 成员?
蒋晟 2004-07-06
  • 打赏
  • 举报
回复
Limitations of _AFXEXT
You can use the _AFXEXT pre-processor symbol for your extension DLLs as long as you do not have multiple layers of extension DLLs. If you have extension DLLs that call or derive from classes in your own extension DLLs, which then derive from the MFC classes, you must use your own preprocessor symbol to avoid ambiguity and linker errors such as the following:
Wnd3.obj : error LNK2001: unresolved external symbol "protected: static struct AFX_MSGMAP const CWnd2::messageMap" (?messageMap@CWnd2@@1UAFX_MSGMAP@@B)
The problem is that in Win32, you must explicitly declare any data as _declspec(dllexport) if it is to be exported from a DLL, and declare any data as _declspec(dllimport) if it is to be imported from a DLL. When you define _AFXEXT, the MFC headers make sure that AFX_EXT_CLASS is defined correctly. When you have multiple layers, one symbol such as AFX_EXT_CLASS is not sufficient because an extension DLL may be exporting new classes as well as importing other classes from another extension DLL.

To deal with this problem, use a special pre-processor symbol that indicates you are building the DLL itself versus just using the DLL. For example, imagine two extension DLLs (A.DLL and B.DLL). They each export some classes in A.H and B.H, respectively. B.DLL uses the classes from A.DLL. The header files would look something like this:

// A.H
#ifdef A_IMPL
#define CLASS_DECL_A _declspec(dllexport)
#else
#define CLASS_DECL_A _declspec(dllimport)
#endif

class CLASS_DECL_A CExampleA : public CObject
{ ... class definition ... };

// B.H
#ifdef B_IMPL
#define CLASS_DECL_B _declspec(dllexport)
#else
#define CLASS_DECL_B _declspec(dllimport)
#endif

class CLASS_DECL_B CExampleB : public CExampleA
{ ... class definition .. };
When A.DLL is built, it is built with /D A_IMPL, and when B.DLL is built, it is built with /D B_IMPL. By using separate symbols for each DLL, you ensure that CExampleB is exported and CExampleA is imported when building B.DLL. CExampleA is exported when building A.DLL and imported when used by B.DLL or some other client. This type of layering cannot be done when using the built-in AFX_EXT_CLASS and _AFXEXT pre-processor symbols. The technique described above solves this problem in a manner not unlike the mechanism MFC itself uses when building its OLE, Database, and Network extension DLLs.
adamx 2004-07-06
  • 打赏
  • 举报
回复
应该可以这样调的
farland 2004-06-19
  • 打赏
  • 举报
回复
有没有好的解决方法?
farland 2004-06-17
  • 打赏
  • 举报
回复
up
sevencat 2004-06-16
  • 打赏
  • 举报
回复
而且这种情况我好像测试过的,假如在有EXE中直接把这个类声明包含进来,前面不加dllimport的话,就会只能找到其他的成员函数,就跟你这种情况一样,假如有dllimport 的话,就会找到动态库里面的这个东西。

你可以试试把AFX_CLASS_EXPORT改成其他的东西,不用他缺省的MFC扩展,
或者改用2003得了。
sevencat 2004-06-16
  • 打赏
  • 举报
回复
是啊,我的环境是vc2003,我还看过了导出函数,确实将这个变量导出来了。
farland 2004-06-16
  • 打赏
  • 举报
回复
我用的也是2003,能具体说一下怎么做吗?
FlyLasly 2004-06-15
  • 打赏
  • 举报
回复
难道需要在程序中显示的声明?
bluebohe 2004-06-15
  • 打赏
  • 举报
回复
比较忙,没太多时间研究,暂时你可以使用全局变量代替静态成员。二者是一致的
farland 2004-06-15
  • 打赏
  • 举报
回复
“我这样写过的,不会报错。”
请问 sevencat(七猫) 是在动态连接库这样用过吗?
我在改成静态库后就不出错了!
sevencat 2004-06-15
  • 打赏
  • 举报
回复
我这样写过的,不会报错。
farland 2004-06-15
  • 打赏
  • 举报
回复
问题中已经说明了
“在class1.cpp中已经初始化double class1::m_Value=0.0;”


关键不是这个问题,而是DLL导出static 成员的问题
如果在客户程序中不直接调用m_Value,程序是可以编译通过的!
如果有成员函数 double& GetValue(){return m_Value;}或在类的实例中调用m_Value
编译就会出上述错误!
catyou 2004-06-15
  • 打赏
  • 举报
回复
you should define m_Value in .cpp file
lianglp 2004-06-15
  • 打赏
  • 举报
回复
double class1::m_Value ;

在cpp文件里定义就可以了。
sevencat 2004-06-15
  • 打赏
  • 举报
回复
正常,你这个类中根本没有这个static的实例,请在某一CPP文件中声明。
加载更多回复(3)

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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