天天看點

C++調用C# com元件:一個完整的的小例子

    我們知道C#開發效率是非常高的,特别是做一些漂亮的頁面就更适合用它了啊.如果你開發一個桌面應用程式即想性能好點又想頁面漂亮點可以考慮用C++和C#一起用.反正現在Win7都內建NetFramework了,就不用糾結為了裝個C#的應用程式而去再整個NetFramework裝上.可以用C#做成com元件,然後C++去調用.反過來也行.可以C++做成com,然後C#來調用.

下面我舉個簡單的小例子.我用的是VS 2008,作業系統是Win 7.

首先建立一個C# com元件.實作的功能很簡單,就是傳回兩數相加的和.

1.建立一個C# Project,類型就選Class Library.取名ArwenAddCom

2.在項目中添加一個接口,取名IComTest.C++調用com元件中所有的功能隻能通過接口來調用,不能直接調用類或函數

具體代碼:

using System.Runtime.InteropServices; //記得加這個命名空間

namespace ArwenAddCom

{

    [Guid("DA07B88D-29F0-41cf-B3D3-611010E6F3FF")] // guid的産生可以通過vs自帶的工具.點菜單欄上的Tools ->Create GUID,然後選第4個選項.Registry Format.

          //點按鈕New GUID,再點Copy.這樣你就可以把産生的guid複制下來,然後粘貼到這個地方來.當然那個大括号得去掉.後面需要用到guid的地方也用這方式産生

    [ComVisible(true)]

    public interface IComTest        //記得用修飾符public

    {

        [DispId(1)]       //如果還要添加其他函數就繼續來個[DispId(2)],[DispId(3)]加在函數前面

        int Plus(int one, int two);

    }

}

3.添加一個類ComTest,繼承接口IComTest,具體代碼

using System.Runtime.InteropServices;

namespace ArwenAddCom

{

    [Guid("04F4DC83-8883-4a03-BDBC-92D8630ECC1F")]

    [ClassInterface(ClassInterfaceType.None)]

    public class ComTest : IComTest

    {

        public int Plus(int a, int b)

        {

            return a + b ;

        }

    }

}

4.把AssemblyInfo.cs中的[assembly:ComVisible(false)]改成[assembly: ComVisible(true)].右擊項目名打開屬性視窗,點标簽Build,選中Register for COMinterop.

如果不想把生成的dll共享,把它放到GAC中的程式集裡.工作到此完成.點選build,在bin目錄中會找到一個ArwenAddCom.dll檔案.這個檔案就是我們需要的com元件了.另外還會看到一個檔案ArwenAddCom.tlb,正常情況應該有的.如果萬一沒這個tlb檔案也可以後面通過一些指令調用dll檔案去生成它.反正C++調用時dll,tlb檔案是不能少的.

如果想把dll放到GAC中則還要做第五步後再build

5.生成snk檔案,并添加到項目中(可選的步驟)

先打開VS指令視窗,有點像用cmd打開的dos視窗.在開始簡單找到vs 2008,在visual studio tools下面有個Visual studio commandprompt.點選打開它

預設顯示c:\windows\system32.你可以先切換到其他視窗.比如輸入D:再回車就切換到D盤的路徑下了再輸入cd D:\temp切換到temp目錄.cd加任何路徑就可以切換到d盤任何地方

然後輸入指令sn–k ArwenAddCom.snk 再回車,就會在temp目錄下生成一個snk檔案.把ArwenAddCom.snk拷貝到項目的根目錄中.和csproj檔案相同的目錄.

打開項目屬性視窗,點标簽Signing,選中Sign the assembly.并在下面的下拉清單中點browse,然後彈出一個對話框來,選中ArwenAddCom.snk

再次點build生成dll檔案.

C++調用 C# com元件

1.調用前要先把com元件注冊才行.

如果你剛調用dll和則build生成dll是在同一台電腦上則不用注冊了.因為build C#的工程時選了Register for COMinterop.就自動給你注冊了

如果不在同一台電腦上,那就要另外去注冊,要真正開發桌面開發程式人家拿個安裝程式去用時自然要重新注冊的.這種情況下肯定不能手動注冊,是通過寫代碼. 這裡為了簡單起見就隻講下怎麼手動注冊

跟生成snk檔案一樣要用到vs指令視窗.如果是沒有用到snk檔案的dll注冊.先在vs指令視窗中把路徑切換到開始生成的dll所在的目錄.dll随便放哪都一樣,隻要找到那目錄就行.

如果是是使用了snk檔案,則通過gacutil /i ArwenAddCom.dll 将dll放入GAC中

再通過REGASM ArwenAddCom.dll  /tlb:ArwenAddCom.tlb即可注冊dll并生成tlb檔案.

補充:

如果已經有tlb檔案隻注冊的話就是REGASM ArwenAddCom.dll,            如果是單獨想生成tlb檔案是tlbexp /out:ArwenAddCom.tlb  ArwenAddCom.dll.

另外還可以通過REGASM /regfile:ArwenAddCom.reg ArwenAddCom.dll生成一個reg注冊腳本檔案,你可以輕按兩下這個腳本檔案去注冊.

2.注冊完了就可以在代碼中用了,先建立一個C++ project,類型選Win32 Console Application

project名字取UseCsharpCom,在向導頁面點finish.把ArwenAddCom.tlb檔案拷貝到項目的任何目錄下.我就放在D:\UseCsharpCom\UseCsharpCom.我們會看到一個UseCsharpCom.cpp檔案,輕按兩下打開把預設生成的代碼全部删掉.敲入下面代碼:

#include "stdafx.h"

#include <iostream>

#import "..\UseCsharpCom\CsharpComTest.tlb" named_guids raw_interfaces_only

void _tmain(int argc, _TCHAR* argv[])

{

    CoInitialize(NULL);

   CsharpComTest::IComTestPtr ptr;       //類似明志一個指向接口的指針

   ptr.CreateInstance(CsharpComTest::CLSID_ComTest);    //執行個體化一個類

   //這個地方有一點點奇怪我也還沒弄懂.在C#中的函數是int Plus(int,int).但類型在這裡都轉成long了.另外就是我們不能直接

  //來個long a = ptr->Plus(1,2);這樣得不到a = 3,反正會出錯.這裡函數Plus的參數變成三個了long Plus(long,long,long *).其中最後一個指針得兩數相加的結果

   long a = 1;

   long * lPtr = &a;

    ptr->Plus(1,2,lPtr);

    std::cout<<a;

}

如果前面把dll放到GAC中,此時就可以正确運作了.得到結果3

如果沒有把dll放到GAC中,則必須把dll檔案拷貝到有UseCsharpCom.exe這個檔案的目錄下.