2013-06-22 21 views
1

我有一個C++/CLI程序集(MyAssembly)中的公共靜態類,它包含一個接受本機參數的公共靜態方法。導出C++/CLI本機類(C4679)

#pragma make_public(nativeTypeA) 

namespace namespaceA 
{ 
    public ref class MyClass : namespaceB::MyClass 
    { 
    public: 
     static managedTypeA^MethodA(nativeTypeA param); 
     static managedTypeB^MethodB(nativeTypeB param); 
    } 
} 

我想將此方法公開給另一個C++/CLI程序集。託管程序集的編譯罰款,但引用它的組件(CallingAssembly)生成方法b以下警告:

warning C4679: 'namespaceA::MyClass::MethodB' : could not import member 
This diagnostic occurred while importing type 'namespaceA::MyClass ' from assembly 'MyAssembly, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'. 

,因爲它是一個模板類的一個typedef我不能nativeTypeB使用make_public,但是,我使用make_public對於非模板化本機類型(例如nativeTypeA),它可以工作(即編譯CallingAssembly時不需要C4679)。我沒有使用make_public,而是通過this文章中建議的方法,通過預處理器指令將本地類聲明爲public並在本地頭文件中使用__declspec(dllexport)。此外,還必須有條件地排除了「公共」修飾符(通過CLR_ACCESS_MODIFIER)作爲類中還包括其他本地項目:

#ifdef MANAGED 
#define CLR_ACCESS_MODIFIER public 
#ifdef MYASSEMBLY_DEF 
    #define MYASSEMBLY_LINKAGE __declspec(dllexport) 
#else 
    #define MYASSEMBLY_LINKAGE __declspec(dllimport) 
#endif 
#else 
#define MYASSEMBLY_LINKAGE 
#define CLR_ACCESS_MODIFIER 
#endif 

template<> 
CLR_ACCESS_MODIFIER class MYASSEMBLY_LINKAGE nativeTypeB<TT> : public nativeTypeB_base<TT> { 
... 
} 

我也做這個基類nativeTypeB(必要的,以編譯)和它的typedef:

typedef public nativeTypeB<TT> MYASSEMBLY_LINKAGE nativeTypeB; 

我不確定上面的行是否必要,但C4679仍然以任一方式出現。

我已經做了通常的檢查:MANAGED預處理器指令定義了兩個項目; MYAssembly_DEF在MyAssembly中定義;並且我在CallingAssembly中添加了對MyAssembly的引用,並在其鏈接行中添加了對MyAssembly.lib的引用。項目構建順序是正確的,並且沒有缺失的依賴關係,但我仍然獲得C4679。

我可以改變接口來接受非模板類型,但我不想這樣做,因爲它會導致代碼膨脹並且不夠優雅。 This提到,在我的母語班級中正常使用「公共」應該有效。

任何人都可以幫忙嗎?

在此先感謝!

+0

這只是不起作用,模板沒有外部鏈接。使用普通的老式#include。 –

+0

你可以詳細說明如何使用#include完成此操作嗎?如果我只是在調用者的頭文件中包含MyClass.h,我會得到與C4679完全相同的警告以及其他一系列錯誤,例如,類型重新定義,因爲在這兩個程序集中都有同名的類。我試着將MethodB設置爲private,並從MyAssembly中的公共代理方法中調用它,因爲這並沒有刪除警告,這看起來令人驚訝,因爲調用者不應該看到私有方法。 – pdm2011

+0

[編譯器錯誤C2158的最佳解決方法:make \ _public不支持本機模板類型](http://stackoverflow.com/questions/4121249/best-workaround-for-compiler-error-c2158-make-public -does-not-support-native-te) –

回答

1

跨DLL邊界傳遞本機類的對象從來不是一個好主意,因爲它很容易違反一個定義規則。

C++/CLI沒有提供任何幫助,而是提供了生成專門設計用於跨組件共享的託管類型的功能。它還可以防止您通過共享本機類型來追求災難(ODR違規)。您可以使用make_public編譯指示來覆蓋此操作,但會受到一些限制(如無模板)。

共享本地類型的更好方法是通過COM風格的接口。

+0

謝謝 - 很明顯,我試圖不支持。我將修改接口來接受非模板類型。 – pdm2011