2012-02-08 47 views
0

我試圖通過導出爲DLL(在Windows/VS 2010上)來保護一些C++代碼。C++ __declspec(dllexport)函數無法訪問實例變量

在下面var的例子被設置在父類的構造,並且調試器顯示它肯定是設置爲引用東西

測試是在代碼中構建的,該代碼使用包含Test類的DLL。

但當go從上測試的一個實例稱爲(從DLL調用,但調用方法由DLL消費者調用)var是空指針(它的值是0)。

這是一個簡化,因爲我不能分享實際的代碼。

//Headers 

class Base { 
    public: 
    __declspec(dllexport) Base();  
    private: 
    Foo* var; 
}; 

class Test : Base { 
public: 
    __declspec(dllexport) Test(); 
    __declspec(dllexport) void go(); 
private: 
}; 

//Body 

Base::Base() { 
    var = new Foo(); 
} 

Test::Test() : Base() { 
} 

void Test::go() { 
    var->do_something(); 
} 

在消費代碼,標題是

class Base { 
public: 
    __declspec(dllimport) Base(); 
}; 

class Test { 
public: 
    __declspec(dllimport) Test(); 
    __declspec(dllimport) void go(); 
}; 

實際的代碼要複雜得多,但我將不勝感激,如果有人能告訴我是否有已知的與DLLEXPORT實例變量的限制,或者如果我更可能調用Test的空指針的方法,或者它可能是一個dllexport和繼承問題。這段代碼在我將拆分消費者代碼和DLL代碼放在同一個項目中之前工作過,它只是在拆分它之後才破解,我想將dllexporting/dllimporting函數公開給消費者使用的第二組頭。

回答

1

當你從一個地方到另一個地方的「消費代碼」值傳遞Test,你會引起slicing發生,因爲客戶端代碼不知道該變量的計算不正確的大小爲類Test

爲了解決這個問題,你應該聲明在客戶端代碼中的變量爲好,或者你也可以提供某種形式的靜態工廠功能,只允許客戶端代碼的指針傳遞給Test S爲中心,以避免切片。

+0

感謝香港專業教育學院更新了問題,因爲我REA在組合中也有繼承。我試過__declspec(dllexport)Foo * var;但我得到了「__declspec修飾符不適用於此聲明」 – 2012-02-08 22:42:23

+0

@PaulRidgway啊,對不起,我錯了,只是添加'Foo * var'到客戶端的'Base'上(或者你甚至可以用'void * var'如果'sizeof(void *)== sizeof(Foo *)') – 2012-02-08 22:47:15

+0

感謝 - 工作(只嘗試Foo *雖然) – 2012-02-09 17:41:01

0

如果您從提供給客戶的代碼中刪除實例變量,則只有您自己的代碼知道對象的實際大小並可以創建它。從我的頭頂,你有兩種方式去了解這一點:

  1. 供應創建類(工廠方法)的一個實例的CreateTest靜電功能。這裏要做的最好的事情是提供一個純粹的接口(沒有實例變量)。

  2. 如果您只想隱藏班級的特定部分,您可以使用pimpl習語(wikipedia article)。

0

有什麼理由不使用:

#ifdef IN_FOO_PROJECT 
# define fooEXPORT __declspec(dllexport) 
#else 
# define fooEXPORT __declspec(dllimport) 
#endif 

class fooEXPORT exportClass 
{ 
public: 
    void function(void); 
    Foo * var; 
} 

如果你想隱藏你的類(或類的一部分),你可以使用它作爲一個私有成員:

#ifdef IN_FOO_PROJECT 
# define fooEXPORT __declspec(dllexport) 
#else 
# define fooEXPORT __declspec(dllimport) 
#endif 

class classToHide; 

class fooEXPORT exportClass 
{ 
public: 
    void function(void); 
    classToHide * var; 
} 

而在.cpp的:

#include "exportClass.h" 
#include "classToHide.h" 

void exportClass::function(void) 
{ 
    var->function(); 
} 
+0

有很多我想要隱藏的原始類(es)方法,所以不能導出並導入整個事情。我想導出一部分方法,這些方法依次調用其他內部和外部方法,一些是公共的和受保護的 - 它們在DLL中訪問但不在外部。 – 2012-02-09 17:36:12