C++ 導出dll 類成員變量問題debug記錄

今天因爲項目原因需要將ubuntu下的工程移植到windows平臺。在ubuntu下面我們使用的是qmake來構建的工程,在windows上面移植的時候,將工程構建軟件替換爲cmake。

在移植的時候,也在吐槽windows的版本管理,什麼vs2013的庫不能用於vs2015編譯鏈接,debug版本不能鏈接release版本之類的設定。我反正覺得這些設定挺奇葩的,在實際情況中,我們常常需要鏈接一些第三方庫,如果是外部人員提供的話,那麼就會只有release版本,調試起來就很難受了。

在移植成功後遇到了一個問題,這個問題折騰了我還比較久的時間。就是在我們工程中自己編寫的動態庫dll中需要導出類。而在我們類是用單例做成的。所以要導出的類中有一個靜態成員變量。在主程序鏈接的時候一直報錯,沒有找到該靜態變量。

代碼結構類似這樣:

dll h文件

#pragma once

#include "stdio.h"
#ifdef _DLL_INNER
#define _EXPORT _declspec(dllexport)
#else
#define _EXPORT _declspec(dllexport)
//#define _EXPORT _declspec(dllimport)
#endif
class _EXPORT ss
{
public:
	static ss * Ins()
	{
		if (m_ss)
		{
		}
		else
		{
			m_ss = new ss;
		}
		printf("addr :%x\n", m_ss);
		return m_ss;
	}
private:
	static ss * m_ss;
	int aal;
};

dll cpp文件類似這種

#define  _DLL_INNER
#include "defs.h"
#include "stdio.h"
ss * ss::m_ss=0;

主程序 cpp類似這種

#include "defs.h"
#include "stdio.h"
int main(int argc, char * argv[])
{
	ss *a = ss::Ins();
	printf("addr: %x\n",a);
	getchar();
}

在這種情況下編譯vs2015給我報了

錯誤 LNK2001 無法解析的外部符號 "private: static class ss * ss::m_ss" (?m_ss@ss@@0PEAV1@EA) teststatic c:\Users\zheng\documents\visual studio 2015\Projects\teststatic\teststatic\teSt.obj 1

針對於此問題,我能想到的是dll數據段和主程序數據段不通用。於是乎想弄dll共享的數據段,結果也沒有解決這個問題。還有關於導出符號

#define _EXPORT _declspec(dllexport)
#define _EXPORT _declspec(dllimport)

正反也測試了好多次,也是沒有解決這個問題。後來無意間將 dll的文件結構改成如下所示,問題才得以解決:

dll h文件

#pragma once

#include "stdio.h"
#ifdef _DLL_INNER
#define _EXPORT _declspec(dllexport)
#else
#define _EXPORT _declspec(dllexport)
//#define _EXPORT _declspec(dllimport)
#endif
class _EXPORT ss
{
public:
	static ss * Ins();
private:
	static ss * m_ss;
	int aal;
};

dll cpp文件:

#pragma once

#include "stdio.h"
#ifdef _DLL_INNER
#define _EXPORT _declspec(dllexport)
#else
#define _EXPORT _declspec(dllexport)
//#define _EXPORT _declspec(dllimport)
#endif
class _EXPORT ss
{
public:
	static ss * Ins();
private:
	static ss * m_ss;
	int aal;
};

之後問題解決。

總結:函數實現還是放在cpp文件規範比較好。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章