【10】C#實戰篇——C# 調用 C++ dll(C++ 導出函數、C++導出類)

文章目錄

  • 1 導出C++ 類函數 、導出 C++函數
    • 1.1 .h文件
    • 1.2 .cpp 文件
    • 1.3 C# 調用
  • 2 C++與C#數據類型對應
  • 3 保姆級教程(項目搭建、代碼、調用,圖文并茂)

1 導出C++ 類函數 、導出 C++函數

C++ 生成動態庫.dll 詳細教程:
C++ 生成動態庫.dll 及 C++調用DLL,及實際項目中的使用技巧
C++ 生成靜態庫.lib 及 C++調用lib,及實際項目中的使用技巧

1.1 .h文件

#pragma once
#ifndef MATHTEST_H
#define MATHTEST_H//宏定義導出:
#ifndef MATHTEST_ //如果沒有定義 MATHTEST_,就定義MATHTEST_API __declspec(dllexport)
#define MATHTEST_API __declspec(dllexport) //導出
#else
#define MATHTEST_API __declspec(dllimport) //導入
#endif//以C方式導出  C++類函數
class MATHTEST_API mathTest
{public:mathTest();int multiply(int a, int b);//乘法int divide(int a, int b);//除法
};//以C方式導出函數
//extern "C",告訴編譯器這里是C語言代碼//為了使自己建的庫可以在 C/C++ 通用調用,使用 __cplusplus ,
//當C++調用代碼時,__cplusplus 值為1,聲明函數外面就加了一層“extern "C" {}”;
//當C 調用代碼時,__cplusplus 值為0,就相當于沒有“extern "C" {}”;#ifdef __cplusplus 
extern "C"
{
#endif//以C方式導出  C++類函數MATHTEST_API mathTest* CreateMyClass();MATHTEST_API void DeleteMyClass(mathTest* obj);MATHTEST_API int Cmultiply(mathTest* obj,int num1, int num2);//加法MATHTEST_API int Cdivide(mathTest* obj,  int num1, int num2);//減法//以C方式導出 C++函數MATHTEST_API int Cadd(int a, int b);//加法MATHTEST_API int Csubtract(int a, int b);//減法
#ifdef __cplusplus
}
#endif#endif

1.2 .cpp 文件

#include "mathTest.h"/*創建動態庫d11:1.VS創建C++ 空項目MyDLL:編寫.h和.cpp文件在.h文件中宏定義導出圖數2.生成dll文件:右鍵項目-->屬性-->配置類型-->動態庫( .dll)以Debug x64 生成解決方案
*//********************************************* 以C方式導出 C++函數********************************************/
int Cadd(int a, int b)//加法
{return a + b;
}int Csubtract(int a, int b)//減法
{return a - b;
}/********************************************* 以C方式導出 C++類函數********************************************/// 已導出類的構造函數。
mathTest::mathTest()
{return; 
}int mathTest::multiply(int a, int b)//乘法
{return a * b;
}int mathTest::divide(int a, int b)//除法
{return a / b;
}MATHTEST_API mathTest* CreateMyClass()
{return new mathTest();	
}MATHTEST_API void DeleteMyClass(mathTest* obj)
{delete obj;
}
MATHTEST_API int Cmultiply(mathTest* obj, int num1, int num2)//加法
{return obj->multiply(num1,num2);
}
MATHTEST_API int Cdivide(mathTest* obj, int num1, int num2)//減法
{return obj->divide(num1,num2);
}

1.3 C# 調用

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;namespace test
{public partial class Form1 : Form{//extern C ,以C方式導出 C++函數[DllImport("dllTest.dll")]static extern int Cadd(int a, int b);[DllImport("dllTest.dll")]static extern int Csubtract(int a, int b);//extern C ,以C方式導出 C++函數private static IntPtr myClassInstance;  // 定義C++類的實例,用于后面的調用[DllImport("dllTest.dll", CallingConvention = CallingConvention.Cdecl)]private static extern IntPtr CreateMyClass();[DllImport("dllTest.dll", CallingConvention = CallingConvention.Cdecl)]private static extern void DeleteMyClass(IntPtr obj);[DllImport("dllTest.dll", CallingConvention = CallingConvention.Cdecl)]private static extern int Cmultiply(IntPtr obj, int num1, int num2);//加法[DllImport("dllTest.dll", CallingConvention = CallingConvention.Cdecl)]private static extern int Cdivide(IntPtr obj, int num1, int num2);//減法public Form1(){InitializeComponent();}private void button3_Click(object sender, EventArgs e){//以C方式導出 C++函數int Csum = Cadd(10, 5);int Csub = Csubtract(10, 5);string str0 = "動態庫測試 dllTest.dll-- 導出 C++函數:";string str1 = "10 + 5 = " + Csum.ToString();string str2 = "10 - 5 = " + Csub.ToString();listBox1.Items.Add(str0);listBox1.Items.Add(str1);listBox1.Items.Add(str2);//以C方式導出 C++ 類函數myClassInstance = CreateMyClass();int Cmul = Cmultiply(myClassInstance, 10, 5);int Cdiv = Cdivide(myClassInstance, 10, 5);str0 = "動態庫測試 dllTest.dll--導出 C++ 類函數:";str1 = "10 x 5 = " + Cmul.ToString();str2 = "10 ÷ 5 = " + Cdiv.ToString();listBox1.Items.Add(str0);listBox1.Items.Add(str1);listBox1.Items.Add(str2);// 清理C++內存DeleteMyClass(myClassInstance);}}
}  

在這里插入圖片描述

2 C++與C#數據類型對應

C#在調用C++ DLL時,需要通過P/Invoke技術來完成。P/Invoke是.NET Framework用于調用非托管代碼庫的一種方式。在這個過程中,我們需要處理兩種語言之間的數據類型轉換,因為它們的數據類型不完全一致。

基本數據類型對應表
以下是C++和C#之間的一些常見數據類型的對應表(請注意,這并不是一個完全的列表,只是一些常見類型的示例):

在這里插入圖片描述

3 保姆級教程(項目搭建、代碼、調用,圖文并茂)

保姆級教程,從C++ 生成動態庫.dll 到 C#調用C/C++生成動態庫.dll,每一個步驟都非常詳細的截圖、注釋、說明,附原碼;

保姆級教程連接:C#調用C/C++生成動態庫.dll及C++ 生成動態庫.dll ,DllImport()方式導入 C++動態庫.dll方法總結

項目下載 :同一個解決方案下多個項目:C++生成動態庫項目和C#調用項目

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/918339.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/918339.shtml
英文地址,請注明出處:http://en.pswp.cn/news/918339.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Flutter 與 Android NDK 集成實戰:實現高性能原生功能

Flutter 與 NDK 集成實現 Flutter 可以通過 Platform Channels 與原生代碼(包括使用 NDK 編寫的 C/C 代碼)進行交互。以下是實現 Flutter 與 NDK 集成的步驟: 基本步驟 1. 創建 Flutter 項目 flutter create flutter_ndk_example cd flutter_…

elementui cascader 遠程加載請求使用 選擇單項等

背景:小程序與后端使用自定義表單渲染視圖。發現若沒有全選(如:省市縣全部選擇,指定的市3級)在pc端就會無法渲染出已經選擇的區縣名稱。 解決方案:參考官方文檔,設置屬性可獨立勾選element ui c…

Unity WebGL打包后啟動方法,本地方法

引言:常見WebGL開啟方法常需要重新打包點擊Build and Run或者將游戲放到Unity的云服務器上,作為開發者而言這兩個方案一個為了開啟再次打包,另一個直接放到了公開環境都不太合適。所以我們需要一個能在本地開啟測試的WebGL的方法。 解決方案 …

安全引導功能及ATF的啟動過程(五)

安全引導功能及ATF的啟動過程(五) ATF中bl32的啟動 bl31中的runtime_svc_init函數會初始化OP-TEE對應的服務,通過調用該服務項的初始化函數來完成OP-TEE的啟動。對于OP-TEE的服務項會通過DECLARE_RT_SVC宏在編譯時被存放到rt_svc_des段中。該…

Numpy科學計算與數據分析:Numpy入門之多平臺安裝與基礎環境配置

Numpy環境搭建與基礎操作 學習目標 本課程將指導學員在Windows、macOS和Linux三種操作系統上安裝Numpy,并配置開發環境,包括使用Jupyter Notebook和Spyder等IDE的基本操作。通過本課程的學習,學員將能夠獨立搭建Numpy開發環境,并…

內存溢出的原因有哪些,如何排查線上問題?

1. java.lang.OutOfMemoryError: ......java heap space..... 堆棧溢出,代碼問題的可能性極大 2. java.lang.OutOfMemoryError: GC over head limit exceeded 系統處于高頻的GC狀態,而且回收的效果依然 不佳的情況,就會開始報這個錯誤&…

Cesium 無人機視角飛行漫游,截屏

1.實現Cesium模擬無人機離屏渲染,無人機視角飛行漫游。視錐體顯示 具體效果如下地址: 【CESIUM無人機視角飛行截屏】 https://www.bilibili.com/video/BV1zQ89zGE14/?share_sourcecopy_web&vd_source8239ec37df07d6a5d56c9ece00146783

vscode 打開設置

目錄 方法 1(快捷鍵): 方法2,界面操作,有時沒有 方法 1(快捷鍵): 按下:Cmd Shift P 輸入并選擇:Preferences: Open Settings (JSON) 方法2,…

繁花深處:花店建設的時代意義與多元應用—仙盟創夢IDE

花店當第一縷晨光透過花店的玻璃窗,落在帶著露水的玫瑰花瓣上時,這個空間便不再只是商品交易的場所。花店作為城市肌理中充滿生命力的細胞,承載著遠比銷售鮮花更豐富的社會意義。在快節奏的現代生活中,一束鮮花的綻放不僅是自然之…

AtomicStampedReference解決方案

1、通過引入版本戳(stamp)機制解決ABA問題: 每次修改時遞增版本號執行CAS時同時檢查值和版本號即使值相同但版本不同,操作也會失敗2、具體代碼實現 import java.util.concurrent.atomic.AtomicStampedReference;public class AtomicStampedReferenceDemo…

版本控制的詳細說明介紹(已有github賬號版)

說明 如果已經有一個GitHub賬號,這是一個很好的起點!版本控制是一個幫助你管理代碼或其他文件變化的工具,就像給你的項目加了一個“時間機器”,可以隨時回溯歷史、協作編輯,而不會亂套。下面我將從基礎開始,層層展開說明。整個內容分為幾個部分:介紹、原理、用途、操作…

基于Github Pages搭建個人博客站點:hexo環境搭建、本地預覽與發布

步驟確認 Hexo 博客的源文件在哪里安裝 Hexo 命令行工具:npm install -g hexo-cli在源文件目錄中使用 hexo new "文章標題" 創建新文章編輯生成的 Markdown 文件使用 hexo generate 生成靜態文件使用 hexo deploy 部署到這個 GitHub Pages 倉庫設置Hexo博…

Shell腳本實現自動封禁惡意掃描IP

iptables 簡介我們使用iptables工具實現功能iptables 是 Linux 系統上最常用的防火墻工具,可以指定策略。Shell文件創建首先我們先創建文件scanners.shvim /usr/local/bin/auto_block_ip.sh我的目標是每10分鐘自動掃描,再10分鐘內一個IP訪問50次以上就就…

LeetCode_哈希表

哈希表(散列表)一、哈希表二、有效的字母異位詞1、有效的字母異位詞(力扣242)2、贖金信(力扣383)3、字母異位詞分組(力扣49)4、找到字符串中所有字母異位詞(力扣438)三、兩個數組的交集1、兩個數組的交集(力扣349)2、兩個數組的交集 II(力扣350)三、其他…

2.變量和常量

1.變量2.2 變量的基本使用2.3 變量的本質 2.4 變量命名規則與規范 2.5 變量拓展-數組 1.數組的基本使用 2.常量

Java并發核心基礎解析

目錄 一、背景 二、Java線程模型 三、Synchronized實現原理 3.1 鎖的使用 3.2 解釋執行 3.3 JIT執行 3.4 鎖的狀態 3.5 monitorenter 3.5.1 偏向鎖 3.5.2 輕量級鎖 3.5.3 重量級鎖 3.6 monitorexit 3.6.1 偏向鎖 3.6.2 輕量級鎖 3.6.3 重量級 四、可見性的真相…

線程池111

線程池框圖C語言線程池詳解:從基礎到實現通俗理解線程池想象你開了一家快遞站,每天要處理很多包裹派送:?沒有線程池?:每來一個包裹就雇一個新快遞員,送完就解雇問題:頻繁招聘解雇成本高(線程創…

Qt-Advanced-Docking-System

直譯一下 : 先進的停靠系統 github: mfreiholz/Qt-Advanced-Docking-System: Advanced Docking System for Qt 這是這個項目的起源 這個最后一次更新: githubuser0xFFFF/Qt-Advanced-Docking-System: Advanced Docking System for Qt 這是另一個人復刻…

湖南(源點咨詢)市場調研 如何在行業研究中快速有效介入 中篇

我們接著起頭篇來說邁克爾波特認為一個行業內存在著五種基本競爭力量,即潛在入侵者、替代產品、供方、需方以及行業內現有競爭者。如附圖:即:同行業內現有競爭者的競爭能力、潛在競爭者進入的能力、替代品的替代能力、供應商的討價還價能力、…

【無標題】消息隊列(Message Queue)是一種**進程間通信(IPC)機制

消息隊列(Message Queue)是一種進程間通信(IPC)機制,它允許進程通過在隊列中添加和讀取消息來交換數據。與管道(命名/匿名)相比,消息隊列具有結構化消息、異步通信和消息持久化等特點…