1. 程式人生 > >C++ 匯出dll 類成員變數問題debug記錄

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" (

[email protected]@@[email protected])teststaticc:\Users\zheng\documents\visual studio 2015\Projects\teststatic\teststatic\teSt.obj1

針對於此問題,我能想到的是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檔案規範比較好。