2016-05-12 87 views
0

我有一個interop類,添加功能非常麻煩,因爲它涉及很多行。比方說,我需要有方法,通過ID我得讓你的ID如下:如何根據VS2013的委託定義生成C#委託,方法等?

public class MyInterop 
{ 
    public class WCFDTypes 
    { 
     //.... 
     public delegate int GetInt_Delegate(int id); 
     //... 
    } 

    public class DTypes 
    { 
     //.... 
     public delegate int DotNetInterface_GetInt_Delegate(int id); 
     //... 
    } 

    public WCFDTypes.GetInt_Delegate GetInt; 

    //... 

    private DTypes.DotNetInterface_GetPlotLabel_Delegate Nat_GetInt; 

    //... 

    public MyInterop(string moduleName) 
    { 
     DelegateBuilder builder = new DelegateBuilder(moduleName); 

     //... 
     Nat_GetInt = Build<DTypes.DotNetInterface_GetInt_Delegate>(builder);   

     //.. 
    } 

    //... 

    GetInt = (int id) => 
    { 
     return NatGetInt(id); 
    } 


    public MyInterop(string moduleName) 
    { 
     //... 
     Nat_GetInt = Build<DTypes.DotNetInterface_GetInt_Delegate>(builder);   

     //.. 
    } 


    public MyInterop(MyApplication, string address) 
    { 


     //... 
     GetInt = client.GetInt;   

     //.. 
    } 
} 

解釋這已經超出了這個問題的範圍。我只想知道如何生成一些東西,即使沒有返回類型或參數只是非變量部分(當然基於像GetInt這樣的函數名)來糾正位置(包括內部類,2個方法聲明和2個構造函數)。

我正在查看片段,但我發現的例子非常基本。

+1

這當然是最糟糕的做法。爲什麼不能使用[DllImport]或C++/CLI包裝程序完全不清楚。 –

+0

這不是我的代碼。正如我所說,這超出了這個問題的範圍。 –

+0

加上它使用本機dll的DllImport。也適用於WCF的外部插件。 –

回答

1

您可以使用System.Reflection中的類從程序集中讀取委託定義。

Assembly asm = Assembly.LoadFrom(assemblyFile); // path to file 
Type[] types = asm.GetTypes(); 

Here,建議您可以識別委託類型與像的方法:

public bool IsDelegate(Type type) 
{ 
return type.IsSubClassOf(typeof(Delegate)) || type==typeof(Delegate); 
} 

或者用gettype(串)加載一個類型的名稱,你知道的。

而且here微軟筆記(重點煤礦):

公共語言運行時提供了每個委託類型的Invoke方法,用相同的簽名委託。您不必從C#,Visual Basic或Visual C++顯式調用此方法,因爲編譯器會自動調用它。 當您想要查找委託類型的簽名時,Invoke方法在反射中很有用。

所以使用這樣獲得的MethodInfo,告訴你委託的帕拉姆和返回類型:

MethodInfo methodInfo = delegateType.GetMethod("Invoke"); 

瞭解這些我希望你現在就可以生成你所需要的。可以在運行時生成一個方法。請參閱here或搜索「發出動態方法和組件」。

但是你可以代替編寫源代碼(如您的片段),以供以後編輯文件,如果你願意,你可以用自動化的System.CodeDom.Compiler彙編,例如:

CodeDomProvider provider = CodeDomProvider.CreateProvider("CS"); // source language 

CompilerParameters compParams = new CompilerParameters(); 
compParams.IncludeDebugInformation = true; 
foreach (string refAsm in referencedAssemblies) { 
    compParams.ReferencedAssemblies.Add(refAsm); 
} 
// etc 

CompilerResults res = provider.CompileAssemblyFromSource(compParams, codeSource); 

if (res.Errors.Count > 0) { 
    // display & throw 
} 

codeSource這裏不是源文件的路徑,而是包含實際源代碼的一個或多個字符串。因此,您甚至可以生成並編譯源代碼,而無需將其寫入文件的中間步驟。