c******s 发帖数: 270 | 1 要被继承的类(DllObject)定义在Project A, 用DLL导出. 而子类(MyClass)定义在
Project B.
在Project A中, 我定义了宏MYDLL_BUILD.
// Config_Project_A.h
#if !defined(MYDLL_BUILD)
# pragma comment(lib, "myDll.lib")
#endif
#if defined(MYDLL_BUILD)
# define MYDLL_API __declspec(dllexport)
#else
# define MYDLL_API __declspec(dllimport)
#endif
// DllObject.h
class MYDLL_API DllObject
{
public:
virtual ~DllObject() {}
protected:
DllObject() { m_count = 3; }
private:
int m_count;
};
在Project B中, 宏MYDLL_BUILD没有被定义.
// MyClass.h
class MyClass : public DllObject
{
public:
~MyClass(){}
MyClass() { m_data = 20; }
private:
int m_data;
};
在Visual Studio里面build的时候碰到如下错误:
2>Test_Entry.obj : error LNK2019: unresolved external symbol "__declspec(
dllimport) public: virtual __thiscall ADAI::DllObject::~DllObject(void)" (__
imp_??1DllObject@ADAI@@UAE@XZ) referenced in function "public: virtual __
thiscall MyClass::~MyClass(void)" (??1MyClass@@UAE@XZ)
2>Test_Entry.obj : error LNK2019: unresolved external symbol "__declspec(
dllimport) protected: __thiscall ADAI::DllObject::DllObject(void)" (__imp_??
0DllObject@ADAI@@IAE@XZ) referenced in function "public: __thiscall MyClass:
:MyClass(void)" (??0MyClass@@QAE@XZ)
2>c:\Users\Adai\Documents\Visual Studio 2010\Projects\Test_Main\Debug\Test_
Main.exe : fatal error LNK1120: 2 unresolved externals
网上搜了一圈,大部分都说.lib没有找到. 但我确认路径和myDll.lib都添加到设置里面
了.
让我更困惑的是, 当我把
class MYDLL_API DllObject
换成是
class __declspec(dllexport) DllObject
之后, 编译能顺利通过, 程序也能正常运行.
谁能帮忙解释一下么?
我也查了DllObject的preprocessed file, 里面看到的是
class __declspec(dllexport) DllObject
让我更加搞不明白了. |
b***i 发帖数: 3043 | 2 你这个是c++ name mangling导致的问题, 你看看 dll里面到底是什么名字
然后,这个问题具体叫inheritance across dll border, linux很容易解决这个问题。
微软的,就不清楚了。
你试试一般extern "C"放函数前防止mangle。做好了告诉我们一声。
另外,linker option /Force:UnRESOLVED也要试试
【在 c******s 的大作中提到】 : 要被继承的类(DllObject)定义在Project A, 用DLL导出. 而子类(MyClass)定义在 : Project B. : 在Project A中, 我定义了宏MYDLL_BUILD. : // Config_Project_A.h : #if !defined(MYDLL_BUILD) : # pragma comment(lib, "myDll.lib") : #endif : #if defined(MYDLL_BUILD) : # define MYDLL_API __declspec(dllexport) : #else
|
c******s 发帖数: 270 | 3 我在DllObject.h 里面加了一个函数,然后添加了一个DllObject.cpp文件.
没有任何其他的改动,settings 也和原来一样.
这样编译就通过了,程序运转正常. 希望有人帮忙解释一下原因.
// DllObject.h
MYDLL_API int foo(int n);
class MYDLL_API DllObject
{
public:
virtual ~DllObject() {}
protected:
DllObject() { m_count = 3; }
private:
int m_count;
};
// DllObject.cpp
int foo(int n)
{ return 0; } |
b***i 发帖数: 3043 | 4 你用的是什么版本的编译器?express?
【在 c******s 的大作中提到】 : 我在DllObject.h 里面加了一个函数,然后添加了一个DllObject.cpp文件. : 没有任何其他的改动,settings 也和原来一样. : 这样编译就通过了,程序运转正常. 希望有人帮忙解释一下原因. : // DllObject.h : : MYDLL_API int foo(int n); : class MYDLL_API DllObject : { : public: : virtual ~DllObject() {}
|
c******s 发帖数: 270 | 5 Professional 和 Express 都试了,都一样的
【在 b***i 的大作中提到】 : 你用的是什么版本的编译器?express?
|
b***i 发帖数: 3043 | 6 那个判断是不是在dll中的宏是你自己写的?
我用vs自动提供的挺好的。你知道怎么让vs自动提供这个宏,包括#ifdef吗?
【在 c******s 的大作中提到】 : Professional 和 Express 都试了,都一样的
|
c******s 发帖数: 270 | 7 没太明白你的意思?
我猜你说的是Preprocessor, 在Project A里面我定义了, 在Project B里面没有定义.(
project->properties->c/c++->preprocessor)
【在 b***i 的大作中提到】 : 那个判断是不是在dll中的宏是你自己写的? : 我用vs自动提供的挺好的。你知道怎么让vs自动提供这个宏,包括#ifdef吗?
|
b***i 发帖数: 3043 | 8 能把相关定义全部列出来吗?标明所在文件
另外,我的意思是说,我直接用向导自动生成了你所需要的宏,而且是在编译或者链接
的命令行参数中出现的,你这个似乎是自己手动加的。我前面是过,自己手动加也是不
行。
.(
【在 c******s 的大作中提到】 : 没太明白你的意思? : 我猜你说的是Preprocessor, 在Project A里面我定义了, 在Project B里面没有定义.( : project->properties->c/c++->preprocessor)
|
c******s 发帖数: 270 | 9 是的,我是手动添加的。
在Project A的Properties->C/C++->Preprocessor的Preprocessor Definitions里添加
MYDLL_BUILD.
不是针对文件的,是针对Project.
【在 b***i 的大作中提到】 : 能把相关定义全部列出来吗?标明所在文件 : 另外,我的意思是说,我直接用向导自动生成了你所需要的宏,而且是在编译或者链接 : 的命令行参数中出现的,你这个似乎是自己手动加的。我前面是过,自己手动加也是不 : 行。 : : .(
|
b***i 发帖数: 3043 | 10 用自动向导生成dll, export symbol, 然后把dll项目变成主项目的reference。基本就
可以了。把dll的目录加入主项目的include里面去,这样直接写#include "mydll.h"
dll的项目用不着lib。编译的时候lib的函数是要加到exe里面去的,而dll的目的是你
编译的程序里面没有这个函数,在运行的时候在加载到内存中。
【在 c******s 的大作中提到】 : 是的,我是手动添加的。 : 在Project A的Properties->C/C++->Preprocessor的Preprocessor Definitions里添加 : MYDLL_BUILD. : 不是针对文件的,是针对Project.
|