2011-11-16 106 views
0

當我們創建directshow過濾器並註冊它時,靜態變量/函數會在同一過濾器的多個實例中共享。我相信這也適用於其他ActiveX控件。例如,如果我嘗試使用類似的東西;DirectShow過濾器中的靜態用法

static int counter = 0; 

void someFunction() { 
    counter++; 
    // trace result here 
} 

如果我開始相同的過濾器的另一個實例,二審不從0開始,但在那裏留下第一個實例計數器。然後他們開始異步增加同一個計數器。

我的問題是,有沒有什麼聰明的方法來阻止DirectShow過濾器的靜態變量之間的共享?這聽起來可能很愚蠢,但如果我們註冊具有不同GUID的相同過濾器(通過使用不同的GUID和文件輸出重新編譯同一項目),靜態變量不再共享,因爲它們是兩個不同的過濾器,對吧?那麼,有什麼辦法可以使用相同的過濾器來模擬這一點,但保持靜態?

我想要做的是使用一個庫中有許多靜態用法。擺脫所有的靜態變量/函數是非常困難的。我試圖使用的庫使用Ansi C等舊標準,並沒有真正的面向對象的設計。所以封裝不是很容易。大部分功能都在全球空間,而不是在課堂上。請記住這一點。如果我保留靜態圖像,過濾器的單個實例工作正常,但由於共享(靜態)變量,其他實例開始變得混亂。

+1

你必須採用_hard_方式 - 在圖書館週圍創建一個包裝並以面向類的方式使用它。過濾器是共享相同進程空間的對象,只有移動靜態可以幫助你在這裏,無論是類成員還是其他地方,比如TLS。 –

回答

0

它實際上並不是特定於DirectShow,問題是典型的問題:我應該在我的類的多個實例中使用靜態變量。

智能答案:如果你不想使用靜態變量 - 不要。過濾器的每個實例都是一個類的獨立實例。使用它的成員變量,不要使用全局變量。

我想要做的是在 它使用許多靜態用法庫。擺脫所有的靜態變量/函數是非常困難的。

將所有靜力學放入一個大類中,例如「狀態」並且每個過濾器具有這個「狀態」的單獨實例。這是真正的首選方式。

另一種解決方案是將所有靜態內容移入子DLL並將其加載進程外,以便每個實例由獨立的進程託管。儘管從技術上講,這可以直接解決問題 - 也就是說,在子進程中,所有靜態方法都保持靜態,同時每個擁有者過濾器都擁有一個單獨的副本,但實現進程外DLL和進程間通信所需的知識基本上假定您可以成功實施前一段中提到的第一個「國家」解決方案。

+0

謝謝你的建議。由於似乎沒有更好的辦法,我接受這個答案(直到某個英雄出現時帶有頂級魔法技巧;))。 –