15

我已經搜索了很多Web和StackOverflow,但是似乎無法爲我的下列問題找到明確的答案。將跨平臺C++庫移植到Windows Phone 8平臺

語境:

我期待端口一組C++助手庫來使用了Windows Phone 8(WP8)平臺使用。從歷史上看,這些庫是作爲靜態庫(而不是DLL)構建的。

我已經成功編寫了WP8特定的代碼,以便使用WP8提供的API(使用WP API QuickStart doc作爲參考點),可以兼容和構建針對ARM的庫。由於必須用WinRT的ThreadPool替換經典的Win32線程調用,因此只有一個庫(例如Lib1)需要使用WinRT擴展(/ ZW標誌)。

構建Lib1時,出現以下警告: 警告1警告LNK4264:將用/ ZW編譯的目標文件歸檔到靜態庫中;請注意,在創作Windows運行時類型時,不建議使用包含Windows運行時元數據的靜態庫進行鏈接。

- 尋找這個警告,我發現this article,他說: 「如果你消耗,創造公開裁判班,公共接口類,或公共價值類的靜態庫,鏈接器提出了這樣的警告可以放心地忽略了。警告如果靜態庫不生成在庫本身之外使用的Windows運行時組件,靜態庫中的公共組件將在編譯時運行,但不會在運行時激活任何用於其他組件或應用程序的Windows運行時組件必須在動態鏈接庫(DLL)中實現。「

在Lib1中,ClassA包含使用WinRT ThreadPool調用的函數。 ClassB函數由ClassB調用,它們只是將常規的HANDLE和DWORD返回給ClassB。

代碼示例:

// ClassA.cpp 
HANDLE WINAPI ClassA::CreateThread(/* Params that are usually passed to Win32 CreateThread */) 
{ 
    // Do WinRTThreadPool stuff to create WorkItem 
    auto workItem = ref new Windows::System::Threading::WorkItemHandler([=](Windows::Foundation::IAsyncAction^) 
    // More code that eventually results in a Win32 Handle 

    return handle; 
} 

// ClassB.cpp 
Handle handle = ClassA::CreateThread(/* Params that are usually passed to Win32 CreateThread */); 

ClassA的職能將只被稱爲ClassB的,從內部LIB1,和ClassB然後可以通過鏈接LIB1應用程序使用。

最後,我的問題:

  1. 能否C++是做消耗WinRT的擴展(/ ZW)庫, 當靜態庫構建,通過的Windows Phone使用8個應用程序?

  2. 能的C++庫(LIB1)是消耗的WinRT擴展 (/ ZW),當作爲靜態庫構建,可通過的Windows Phone 8個 應用,儘管使用的警告?

  3. 如果答案是否定的,以任何一個問題,我將在各自的圖書館創建的所有類的WinRT的 組件封裝, 像this article演示與曼德爾布羅算法?還是有什麼我失蹤?

在此先感謝您提供的任何輸入內容。

回答

5

問題1 是的,只要你不使用不允許的手機上的任何的API,如Win32中,MFC等一些標準C的功能讓他們身邊的一些限制;例如,你只能對應用程序本地區域中的文件調用fopen。當然,您只能從C++代碼訪問靜態庫中的功能。這種情況是我喜歡稱之爲「普通舊C++」的情況。它工作正常。

問題2 是的,只要您在該靜態庫中定義的任何ref類只用於從該靜態庫中使用。所以在你的例子中,只要A類是一個普通的舊C++類,你會沒事的。基本上,你不能在.NET程序集中擁有與公共類相同的公有類的引用類,因爲這需要一些COM-on-steroids的魔力,並且只能編譯到Windows運行時組件中。如果你有簡單的舊C++代碼包裝你對任何ref類代碼的調用,並且使用靜態庫的代碼會以一種普通的舊C++方式使用它,那麼你很好。邏輯表明,你將無法將WinRT類型從靜態庫中傳出,儘管我還沒有測試過這種假設。

問題3 我相信你引用的文章忽略了事實,即在一個靜態庫的代碼可以訪問REF類等,所以不用擔心,你不必寫圍繞Windows運行時組件的包裝靜態庫。如果你想讓你的靜態庫中的代碼通過「公共類」(在.NET程序集的意義上)可用,你只需要這樣做。

需要記住的是,您仍然在爲「windows store」構建一個靜態庫。它是本機代碼,但它仍然可以執行所有C++/CX的東西,它只是不包含COM激活的東西,以允許在靜態鏈接的C++場景之外訪問其中定義的類型。