2013-03-04 150 views
1

我的應用程序分爲C#(託管代碼)和C++(非託管代碼)兩部分。這兩個部分都會頻繁地調用對方,並且通常會在它們之間傳遞字符串。我想知道最好的和沒有錯誤的方式來做到這一點。託管代碼和非託管代碼之間的調用代碼

我分問題兩個部分

  1. 當從託管到非託管代碼調用,我使用字符串構建傳遞從託管到非託管:

    [DllImport("SomeXYZ.dll")] 
    // enter code here 
    
    private void XYZ(string text) 
    { 
        StringBuilder builder = new StringBuilder(); 
        builder.Append(「Var1」); 
        FromManagedtoUnmanaged(builder); 
    } 
    

    C++代碼:

    extern "C" 
    { 
    int _declspec(dllexport) FromManagedtoUnmanaged(char* var1); 
    } 
    
  2. 從非託管到託管,我使用的函數指針giv C#函數的EA函數參照C++函數:

    C#代碼

    [DllImport("SomeXYZ.dll")] 
    public static extern void SetCallback(Callback fn); 
    public delegate void Callback(string text); 
    public Callback mInstance; 
    
    private void ABC(string text) 
    { 
        mInstance = new Callback(SomeFunctionName); 
        SetCallback(mInstance); 
    } 
    

    C++代碼,在頭文件:

    extern "C" 
    { 
    void __declspec(dllexport) __stdcall SetCallback(Callback handler); 
    void __declspec(dllexport) __stdcall SendReceiveMessage(char* arr1); 
    } 
    

    而在cpp文件:

    void __stdcall SetCallback(Callback handler1) { 
        Handler = handler1; 
    } 
    
    void __stdcall SendReceiveMessage(char* arr1) { 
        Handler(arr1); 
    } 
    
    void SendMsg(int SomeVar) 
    { 
        char *str; 
        str = new char[1024]; 
        sprintf(str, 「<body>%d</body>」, SomeVar); 
        SendReceiveMessage(str); 
    } 
    
+0

你確切的問題是什麼?第二部分在哪裏?就我所能看到的,您不使用'StringBuilder',而使用'string'。 – 2013-03-04 15:24:57

+0

@ZdeslavVojkovic我猜他的意思是在'FromManagedtoUnmanaged'的實現中,你不會將'StringBuilder'傳遞給函數,通常我不這麼認爲 – 2013-03-04 15:28:43

+0

。由於它是非託管的,他不能使用'StringBuilder'。對於互操作,通常將'StringBuilder'發送給函數,這些函數會改變字符串的狀態,因爲字符串是不可變的。 – 2013-03-04 15:33:29

回答

1

最好的是創建一個輕的C++/CLI程序集 兩者之間。這是什麼/爲什麼這種語言已被創建。

這個C++/CLI層將無縫集成到您的C#項目中,可以像任何.net資源那樣訪問,並且C++/CLI可以無縫地調用任何本機C++代碼。

我已經停止將C++直接調用到C#代碼中,因爲我已經嘗試了這種技術。

如果您從未聽說過C++/CLI,here's a concise tutorial in pdf format

+0

好吧,它只是在寫入時沒有錯誤,並且引入了另一個程序集來調用一個使部署稍微複雜的方法。 – 2013-03-04 15:47:27

+0

@ZdeslavVojkovic沒錯。我已經相應編輯了。然而,根據我的經驗,**它很容易在錯誤的函數名稱**中出錯,對於初學者甚至非初學者程序員來說,這是完全不可讀的...... C++/CLI已經完全贏得了遊戲的勝利對我來說。 – 2013-03-04 15:53:52

+0

對於普通的C函數,名稱修改不是一個問題,但我同意選擇正確的參數類型和除了基本類型之外的任何東西的符號「[MarshalAs]」都非常容易出錯,特別是對於沒有經驗的用戶。 – 2013-03-04 15:58:28