调用一个在动态链接库里的模板类时出现 LNK2019 错误的问题

调用一个在动态链接库里的模板类时出现 LNK2019 错误的问题

问题描述:

我正在开发一个科学计算库,其中一个叫 Number 的项目是动态链接库,这个库里面有一个普通类 real 和一个模板类 complex。在另一个项目中,我调用 real 类的时候完全没问题,但是当调用 complex 类时链接器报 LNK2019。我实在看不出 real 和 complex 这两个类除了是否模板类这个区别之外的其它区别,所以问题真的出在类模板上吗?

 

下面是动态链接库 Number 项目的代码片段

number.h

#pragma once
#ifdef NUMBER_EXPORTS
#	define NUMBER_API __declspec(dllexport)
#else
#	define NUMBER_API __declspec(dllimport)
#	pragma	comment(lib, "number")
#endif // _NUMBER_EXPORTS

#include <iostream>

namespace osl {
    
    class NUMBER_API real {
		double _denominator, _numerator;
		// object_operation.cpp
		inline void simplify();

	public:
		bool known;

		// real.cpp
		inline real();
		inline real(const real& origin);
        // ...
	};

	template<class num = double>
	class NUMBER_API complex {
		num _real, _imag;

	public:
		bool known;

		// complex.cpp
		inline complex();
		inline complex(const complex& cpl);
        // ...
	};
}

real.cpp

#include "pch.h"
#include "number.h"
using std::cout;

namespace osl {
	inline real::real() :
		_denominator(1), _numerator(0), known(false)
	{}

	inline real::real(const real& origin) :
		_denominator(origin._denominator), _numerator(origin._numerator), known(origin.known)
	{}
       
    // ...
}

complex.cpp

#include "pch.h"
#include "number.h"
#include <gsl/gsl_complex_math.h>
using std::cout;

namespace osl {
	template<class num>
	inline complex<num>::complex() :
		_real(0), _imag(0), known(false)
	{}

	template<class num>
	inline complex<num>::complex(const complex& cpl) :
		_real(cpl._real), _imag(cpl._imag), known(cpl.known)
	{}
    
    // ...
}

调用 real 和 complex 类的控制台应用项目并出现问题的代码片段 (example.cpp)

#include <iostream>
#include "..\Number\number.h"
using namespace std;
using namespace osl;

int main()
{
	real hello;
	hello.console_print();
    // 下面两行引起了问题
	complex<double> cpl;
	cpl.console_print_rect();
	return 0;
}

链接器主要错误

严重性	代码	说明	项目

错误	LNK2019	无法解析的外部符号 "__declspec(dllimport) public: __cdecl osl::complex<double>::complex<double>(void)" (__imp_??0?$complex@N@osl@@QEAA@XZ),函数 main 中引用了该符号	Example

错误	LNK2019	无法解析的外部符号 "__declspec(dllimport) public: void __cdecl osl::complex<double>::console_print_rect(char const *)const " (__imp_?console_print_rect@?$complex@N@osl@@QEBAXPEBD@Z),函数 main 中引用了该符号	Example

求大佬帮帮忙 QWQ

该项目已经在 Github 和 Gitee 开源,旨在简化专业的科学计算编程,需要者自取。

https://github.com/YumiZhan/OSL

https://gitee.com/YumiZhan/OSL

C++的模板类声明和实现最好都写在头文件里,否则编译器在编译时无法确定模板具现化类的符号信息。模板毕竟只是模板,具现化的时候才会展开真正的具体的类型。另外一种临时的解决方式是把complex.cpp也include进你要用的地方。