1. 程式人生 > 實用技巧 >C#利用SWIG呼叫C++的DLL

C#利用SWIG呼叫C++的DLL

/MD編譯的c++DLL可以利用託管C++,/MT編譯的DLL不能利用託管C++與C#粘合,

找了很久,今天偶爾發現了SWIG技術,經測試可以滿足第二中要求,特此記錄一下。

環境:

Win10+VS2019+SWIG4.0.2

1.首先下載SWIG,我是Win10,需要選擇swigwin版

http://www.swig.org/download.html

下載後解壓到指定定目錄,如:D:\swigwin402,為方便呼叫,可以把此路徑新增到系統路徑:

2.建立C#控制檯應用程式SwigCSharp

3.在此解決方案中新增C++動態連結庫專案:SwigC

以上所有由VS自動建立的內容完全不必做任何更改。

4.我在C++dll中新增兩個類CAdd、CMul展示應用效果,

5.向剛才新增的兩個C++類增加程式碼(粗斜體部分):

CAdd.h

#pragma once
class CAdd
{
public:
    CAdd();
    ~CAdd();
    // 測試對C++模組中定義的Class的呼叫  
    int Add(int a, int b);
};

CAdd.cpp

#include "pch.h"
#include "CAdd.h"
CAdd::CAdd() {}
CAdd::~CAdd() {}
int CAdd::Add(int a, int b)
{
    
return a + b; }

CMul.h

#pragma once
class CMul
{
public:
    CMul();
    ~CMul();
    // 測試對C++模組中定義的Class的呼叫  
    int Mul(int a, int b);
};

CMul.cpp

#include "pch.h"
#include "CMul.h"
CMul::CMul() {}
CMul::~CMul() {}
int CMul::Mul(int a, int b)
{
    return a * b;
}

6.在SwigC專案資料夾中新增兩個檔案:SwigC.bat和SwigC.i,內容如下:

SwigC.bat內容

@echo off
swig -csharp -c++ SwigC.i
@echo 'Success'
pause

SwigC.i內容

%module DLLNameWithoutEXT
%{
#include "CAdd.h"
#include "CMul.h"
%}
%include "CAdd.h"
%include "CMul.h"

紅色字可以隨便寫,但是後續生成的c++ DLL的檔名(不含副檔名)要與紅字相同

7.雙擊bat檔案,會自動生成幾個cs檔案和一個cxx檔案:

向C++專案新增SwigC_wrap.cxx檔案,並修改為“不使用預編譯頭”

向C#專案新增四個cs檔案CAdd.cs、CMul.cs、DLLNameWithoutEXT.cs、DLLNameWithoutEXTPINVOKE.cs

全部新增完後項目如圖所示:

8.修改C# 專案的程式碼:

namespace SwigCSharp
{
    class Program
    {
        static void Main(string[] args)
        {
            CAdd add = new CAdd();
            Console.WriteLine("{0}+{1}={2}", 5, 6, add.Add(5, 6));
            CMul mul = new CMul();
            Console.WriteLine("{0}*{1}={2}", 5, 6, mul.Mul(5, 6));
            Console.ReadLine();
        }
    }
}

9.編譯C++dll,並把dll複製到C#輸出目錄中,再編譯執行C# 專案:

10.出錯了!fxxk

11.原來是c++dll是x86的,而c#程式為AnyCPU,修改C#為x86,重新生成C#程式

12.哦耶!

13.把c++dll改為/MT 編譯,重新使用dll,仍然成功!