close
建立Win32新專案: CMathFunc
image 

image

image

按下<完成>, 產生檔案如下, 其中 CMathFunc.cpp 和專案名稱一致

image

進入後在專案上按右鍵,新增一個標頭檔(.h),名字就跟專案名稱一樣

image

image

開始撰寫CMathFun.h框架如下

   1: #pragma once
   2:  
   3: #ifndef CMATHFUN_H
   4: #define CMATHFUN_H
   5:  
   6:  
   7:  
   8:  
   9: #endif

宣告dll呼叫方法,並且定義巨集DLLEXPORT(可自行更改名字), 在方法的前面,將DLL的方法做輸出

   1: #pragma once
   2:  
   3: #ifndef CMATHFUN_H
   4: #define CMATHFUN_H
   5:  
   6:  
   7: #define DLLEXPORT __declspec(dllexport)  //定義巨集DLLEXPORT(可自行更改名字), 在方法的前面,將DLL的方法做輸出
   8:  
   9: extern "C"{
  10:     
  11:   // Returns a + b
  12:   DLLEXPORT double Add(double a, double b);
  13:  
  14:   // Returns a - b
  15:   DLLEXPORT double Subtract(double a, double b);
  16:  
  17:   // Returns a * b
  18:   DLLEXPORT double Multiply(double a, double b);
  19:  
  20:   // Returns a / b
  21:   DLLEXPORT double Divide(double a, double b);
  22: }
  23:  
  24: #endif

再來撰寫方法內容實作部份, 撰寫在CMathFunc.cpp, 並可以定義命名空間CMathFun, 避免與其他函式庫名稱衝突

   1: #include "stdafx.h"
   2: #include "CMathFun.h"
   3: namespace CMathFun{
   4:  
   5:  
   6:  
   7:  
   8:  
   9:  
  10: }

輸入方法

   1:  
   2: #include "stdafx.h"
   3: #include "CMathFun.h"
   4: namespace CMathFun{
   5:  
   6:     double Add(double a, double b)
   7:     {
   8:         return a + b;
   9:     }
  10:  
  11:     double Subtract(double a, double b)
  12:     {
  13:         return a - b;
  14:     }
  15:  
  16:     double Multiply(double a, double b)
  17:     {
  18:         return a * b;
  19:     }
  20:  
  21:     double Divide(double a, double b)
  22:     {
  23:         if (b == 0)
  24:         {
  25:             return -1;
  26:         }
  27:  
  28:         return a / b;
  29:     }
  30:  
  31: }
編譯選項記得支援clr, 否則C#加入參考時會跳出錯誤訊息

image

下圖為不支援clr錯誤訊息, 看得出來是因為沒有勾選 /clr 所造成的嗎? 我是看不出來啦!!!

image

========================================================================================================================================

新增C# Windows Form專案呼叫上面所撰寫的DLL函式庫

專案名稱: CMathFuncClient

image

新增人機介面如左下, 並加入參考

image

選擇CMathFunc.dll

image

開啟Form1.cs

using System.Runtime.InteropServices;

並定義C#呼叫函式, 基本上如果呼叫C版本前面需要加入static表示不需要創建一個物件去呼叫某個方法!

image

   1: using System;
   2: using System.Collections.Generic;
   3: using System.ComponentModel;
   4: using System.Data;
   5: using System.Drawing;
   6: using System.Linq;
   7: using System.Text;
   8: using System.Windows.Forms;
   9: using System.Runtime.InteropServices;
  10:  
  11: namespace CMathFuncClient
  12: {
  13:     public partial class Form1 : Form
  14:     {
  15:         [DllImport("CMathFunc.dll", EntryPoint = "Add", CallingConvention = CallingConvention.Cdecl)]
  16:         static extern double Add(double a, double b);
  17:         [DllImport("CMathFunc.dll", EntryPoint = "Subtract", CallingConvention = CallingConvention.Cdecl)]
  18:         static extern double Subtract(double a, double b);
  19:         [DllImport("CMathFunc.dll", EntryPoint = "Multiply", CallingConvention = CallingConvention.Cdecl)]
  20:         static extern double Multiply(double a, double b);
  21:         [DllImport("CMathFunc.dll", EntryPoint = "Divide", CallingConvention = CallingConvention.Cdecl)]
  22:         static extern double Divide(double a, double b);
  23:  
  24:         public Form1()
  25:         {
  26:             InitializeComponent();
  27:         }
按下按鈕
   1: private void button2_Click(object sender, EventArgs e)
   2: {
   3:     double x = Double.Parse(textBox1.Text);
   4:     double y = Double.Parse(textBox2.Text);
   5:     double z;
   6:     
   7:     z = Add(x, y);
   8:     label1.Text = z.ToString();
   9:     z = Subtract(x, y);
  10:     label2.Text = z.ToString();
  11:     z = Multiply(x, y);
  12:     label3.Text = z.ToString();
  13:     z = Divide(x, y);
  14:     label4.Text = z.ToString();
  15: }

如果正確無誤, 表示你成功利用C# Windows Form呼叫C動態函式庫(dll)

image

================================================================================================================

接下來, 改以C++方式包裝DLL

image

 image

image

image

image

CppMathFunc.h

   1: // CppMathFunc.h
   2: #pragma once
   3: namespace CppMathFunc{
   4:     public ref class Arithmetics
   5:     {        
   6:         public:
   7:         // TODO: 在此加入這個類別的方法。
   8:         Arithmetics(){};
   9:         double Add(double x, double y);
  10:         double Subtract(double a, double b);
  11:         double Multiply(double x, double y);
  12:         double Divide(double a, double b);
  13:     };
  14: }

接下來在CppMathFunc.cpp定義方法實作內容

   1: // CppMathFunc.cpp : 定義 DLL 應用程式的匯出函式。
   2: //
   3:  
   4: #include "stdafx.h"
   5: #include "CppMathFunc.h"
   6:  
   7: namespace CppMathFunc{
   8:     
   9:     double Arithmetics::Add(double x, double y)
  10:     {
  11:         return x+y;
  12:     }
  13:     double Arithmetics::Subtract(double a, double b)
  14:     {
  15:         return a - b;
  16:     }
  17:     double Arithmetics::Multiply(double x, double y)
  18:     {
  19:         return x*y;
  20:     }
  21:     double Arithmetics::Divide(double a, double b)
  22:     {
  23:         if (b == 0)
  24:         {
  25:             return -1;
  26:         }
  27:  
  28:         return a / b;
  29:     }
  30: }
  31:  

編譯選項記得支援clr, 否則C#加入參考時會跳出錯誤訊息

image

========================================================================================================================================

新增C# Windows Form專案呼叫上面所撰寫的DLL函式庫

專案名稱: CppMathFuncClient

image

手動加入參考

image

選擇CppMathFunc.dll

image

   1: using System;
   2: using System.Collections.Generic;
   3: using System.ComponentModel;
   4: using System.Data;
   5: using System.Drawing;
   6: using System.Linq;
   7: using System.Text;
   8: using System.Windows.Forms;
   9: using CppMathFunc;
  10: namespace CppMathFuncClient
  11: {
  12:     public partial class Form1 : Form
  13:     {
  14:         public Form1()
  15:         {
  16:             InitializeComponent();
  17:         }
  18:  
  19:         private void button2_Click(object sender, EventArgs e)
  20:         {
  21:             double x = Double.Parse(textBox1.Text);
  22:             double y = Double.Parse(textBox2.Text);
  23:             double z;
  24:             Arithmetics ar = new Arithmetics();
  25:             z = ar.Add(x, y);
  26:             label1.Text = z.ToString();
  27:             z = ar.Subtract(x, y);
  28:             label2.Text = z.ToString();
  29:             z = ar.Multiply(x, y);
  30:             label3.Text = z.ToString();
  31:             z = ar.Divide(x, y);
  32:             label4.Text = z.ToString();
  33:         }
  34:     }
  35: }

執行結果:

image

 

References:
  1. 在C#中如何使用C/C++所編譯出來的dll?
  2. PInvokeStackImbalance問題
  3. programming-class Lib-C#呼叫c++ 的dll
  4. C/C++ 製作 DLL 教學
arrow
arrow
    全站熱搜

    me1237guy 發表在 痞客邦 留言(1) 人氣()