今天因爲項目原因需要將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文件規範比較好。