Qt C++動態庫SDK在Visual Studio 2022使用(C++/C#版本)

01??

將C++ SDK 集成到 IDE 中

以下是在?Microsoft Visual Studio?平臺下?SDK?的集成。

2.1 Visual Studio 平臺下 C/C++環境配置及集成到 IDE 中

xxx.lib 和 xxx.dll 適合在 Windows 操作系統平臺使用,這里以 VS2022 環境為例。

2.1.1 C/C++ 工程環境配置與集成

1C# SDK?接口文件包含

a、將 a.hb.hc.h

a.cpp?拷貝到用戶指定路徑下。

b、點擊項目?-?屬性?- C/C++ -常規。在附加包含目錄下指定頭文件的路徑。

2、添加庫引用和庫的路徑

a?、 將 提 供 的?a_sdk.dll?,?b.dll?拷 貝 到 程 序 運 行 的 目 錄 下 ; 將

a.lib?拷貝到用戶指定路徑下。

b、點擊項目?-?屬性?-?鏈接器?-?常規。在附加庫目錄中指定?a.lib?的路

徑。

02??

2.1.2 在用戶 C/C++ 項目中使用 SDK

以下為獲取數據的簡單步驟,更詳細的使用方法可以參考提供的?Demo?程序。

添加頭文件,添加庫以后,將dll放在可執行目錄,即可調用外部SDK動態庫使用。

03??

2.2 Visual Studio 平臺下 C#環境配置及集成到 IDE 中

CSharp_Lib 適合在 Windows 操作系統平臺使用,這里以 VS2022 環境為例。

2.2.1 C# 工程環境配置與集成

1、工程文件包含

將?CSharp_Lib?文件夾拷貝到工程目錄下,并把?dll?文件夾相對應?x64?和?x86

的?aa.dll?和bb_sdk.dll?拷貝到工程目錄的運行目錄下。

注意:將C++ DLL給C#上位機使用,有很多語法需要轉換,這個我們會詳細介紹。

04??

C#為例

將C++ 的動態庫依賴的頭文件和源文件轉為.cs格式。

C#需要的模塊

  1. using System;:引用了System命名空間,這是C#中最基礎的命名空間,包含了基本的類和功能,如Console類、Math類等。

  2. using System.Collections.Generic;:引用了System.Collections.Generic命名空間,這個命名空間包含了泛型集合類,如List<T>Dictionary<TKey, TValue>等,這些類在處理數據集合時非常有用。

  3. using System.Linq;:引用了System.Linq命名空間,這個命名空間包含了LINQ(Language Integrated Query)相關的類和功能,LINQ允許在C#中編寫查詢語句來操作數據集合。

  4. using System.Text;:引用了System.Text命名空間,這個命名空間包含了處理字符串和文本的類,如StringBuilder類。

  5. using System.Threading.Tasks;:引用了System.Threading.Tasks命名空間,這個命名空間包含了異步編程相關的類和功能,如Task類和async/await關鍵字。

代碼格式

    namespace?DEVICE{? ? classParameterDefine? ? {? ? ? ??//代碼實現?? ? ? ??public?const?string?a =?"123";? ? }} ? ?

    枚舉格式

      ?public?enum?StatusTypeDef?{? ? RED;?}

      使用C++動態庫的頭文件的結構體的中含有字符串,需要進行轉化。

      • [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]

        ?這是一個特性,用于指定結構體在內存中的布局方式以及如何處理字符串數據。

      • LayoutKind.Sequential

        ?表示結構體中的元素在內存中按它們在代碼中定義的順序進行布局,不會被打亂。這對于與非托管代碼(如C++編寫的DLL)進行交互非常重要,以確保數據在內存中的排列方式匹配。

      • CharSet = CharSet.Ansi

        ?指定了結構體中的字符串使用ANSI字符集。ANSI字符集是一種單字節字符集,通常用于支持英語和其他西歐語言。這對于與需要ANSI字符串的非托管代碼進行交互是有必要的。如果需要支持Unicode字符集,則應使用?CharSet = CharSet.Unicode。這里使用ANSI是為了確保與SDK中的函數參數類型匹配。

      使用C++動態庫的頭文件的字符數組,需要進行轉化。如char a[32];

      C++ 字符數組轉為字符串

      1. [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]:

        • [MarshalAs(...)]

          : 這是一個C#中的特性(attribute),用于指定字段在封送到非托管代碼時應如何處理。它屬于System.Runtime.InteropServices命名空間,因此在使用之前需要引入該命名空間。

        • UnmanagedType.ByValTStr

          : 這個值指定字段應該被封送為固定長度的ANSI字符數組。ANSI字符通常是單字節字符,適合處理不包含Unicode字符的數據。

        • SizeConst = 32

          : 這個值指定了字段在非托管代碼中的大小(以字符為單位)。在這里,SizeConst = 32表示字符數組的長度為32個字符(包括結束符’\0’)。

        ?[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]?//設備IP地址和端口號?public?struct?DeviceNetPara_t?{? ? ?[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]? ? ?public?string?ip_addr;? ? ?public?UInt32 port;?}

        C++ char*轉為字符數組

        1. 特性(Attributes): 特性是用于向程序中的類型、方法或屬性添加元數據的方式。C#中的特性可以用于編譯時檢查以及運行時的行為修改。

        2. StructLayout: 這是一個特性,用于指定結構體在內存中的布局方式。它有幾個參數可以配置,這里主要用到了LayoutKind.SequentialCharSetPack

        3. LayoutKind.Sequential: 這個參數指定結構體中的字段按照它們在代碼中聲明的順序存儲在內存中。這與C/C++中的結構體布局方式一致。

        4. CharSet = CharSet.Ansi: 這個參數用于指定結構體中字符串字段的字符編碼方式。CharSet.Ansi表示使用ANSI字符集來存儲字符串。這意味著每個字符占用一個字節,適用于ASCII字符集。

        5. Pack = 4: 這個參數用于指定結構體字段的對齊方式。Pack = 4表示結構體中的字段按照4字節對齊。這意味著每個字段的起始地址必須是4字節的倍數。這通常用于優化性能,特別是在與非托管代碼(如C/C++庫)交互時。

          ?[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 4)]?//數據?public?struct?Info_t?{??? ? ?[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]? ? ?public?char[] ip;?}

          C++ void* 轉換IntPtr

          1. 特性聲明?[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]

            :

            • StructLayout

              ?是一個C#特性,用于定義結構體在內存中的布局方式。在C#中,結構體默認使用?LayoutKind.Auto,這意味著編譯器可以根據需要重新排列結構體中的字段以優化內存使用。

            • LayoutKind.Sequential

              ?選項強制編譯器按結構體中字段定義的順序在內存中布局這些字段。這對于與非托管代碼(如C/C++代碼)進行交互非常重要,因為你需要確保結構體的布局與非托管代碼期望的布局一致。

            • CharSet = CharSet.Auto

              ?選項指定了非托管字符串的類型。CharSet.Auto?在Windows平臺上通常被解釋為?CharSet.Unicode,但在其他平臺上則可能是?CharSet.Ansi。這確保了字符串在與非托管代碼交互時的正確編碼。

            [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]//異步事件參數public?struct?Args_t{? ??public?IntPtr data; ? ? ? ? ? ? ? ??//數據}

            C++ 回調函數指針轉為C#

            1. 特性(Attribute):

              • [UnmanagedFunctionPointer(CallingConvention.Cdecl)]

                :這是一個特性,用于修飾一個委托(delegate),告訴編譯器這個委托指向的函數是未托管代碼中的函數,并且使用哪種調用約定(Calling Convention)來調用這些函數。

            2. UnmanagedFunctionPointer 特性:

              • UnmanagedFunctionPointer

                :這是一個.NET 特性,用于定義一個委托,該委托指向的函數存在于非托管代碼中(例如C/C++編寫的DLL)。通過這個特性,可以確保.NET 應用程序能夠正確地調用這些非托管函數。

            3. CallingConvention.Cdecl:

              • CallingConvention.Cdecl

                :這是調用約定的一種類型。在這種約定下,函數的調用者負責清理堆棧。這通常用于C語言的函數調用,因此在調用C/C++編寫的函數時,使用這種約定是比較常見的。Cdecl約定通常提供更好的性能,因為它讓調用者(而不是被調函數)負責清理堆棧,從而避免了額外的堆棧操作。

              ? ??// 事件委托類型? ? [UnmanagedFunctionPointer(CallingConvention.Cdecl)]? ??// public delegate void DBL_UserEventCallbackHandleDelegate: 這行代碼定義了一個名為DBL_UserEventCallbackHandleDelegate的委托。? ??public?delegate?void?UserEventCallbackHandleDelegate(int?id, Args_t arg, IntPtr userThis);

              05??

              C++ 動態庫DLL轉為C#

              • DLL導入

                : 通過DllImport屬性,你可以在C#中調用a_sdk.dll中的函數。這意味著你的程序可以利用這個DLL中的功能,例如硬件控制、數據采集等。

              • 字符集

                :?CharSet.Auto允許程序根據運行時環境自動選擇字符集,這在處理不同平臺上的字符串時非常有用。

              • 調用約定

                :?CallingConvention.Cdecl確保了函數調用的參數傳遞和清理方式符合C語言的規范,這對于確保你的C#代碼能夠正確地與非托管代碼交互非常重要。

                // 外部庫,記得的放在可執行文件目錄下[DllImport("a_sdk.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]// 外部庫dll中的函數extern?static?int?ScanDeviceList(ref?IntPtr deviceList,?ref?UInt32 deviceNumber);

                ref如同C++的& 代表引用。IntPtr如同C++的*

                06??

                字節數組轉為結構體

                  // 返回類型:object 表示該方法返回一個類型為 object 的對象。由于 object 是所有類型的基類,返回的值可以是任何類型。// Type type:表示目標結構體的類型public?static?object?BytesToStuct(byte[] bytes,?int?pos, Type type){? ??//得到結構體的大小? ??int?size = Marshal.SizeOf(type);? ??//byte數組長度小于結構體的大小? ??if?(size > bytes.Length + pos)? ? {? ? ? ??//返回空? ? ? ??return?null;? ? }? ??//分配結構體大小的內存空間? ? IntPtr structPtr = Marshal.AllocHGlobal(size);? ??//將byte數組拷到分配好的內存空間? ? Marshal.Copy(bytes, pos, structPtr, size);? ??//將內存空間轉換為目標結構體? ??object?obj = Marshal.PtrToStructure(structPtr, type);? ??//釋放內存空間? ? Marshal.FreeHGlobal(structPtr);? ??//返回結構體? ??return?obj;}

                  其實以目前的AI來看,只要掌握其中一門語言,轉化一下就好。

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

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

                  相關文章

                  大語言模型 LLM 通過 Excel 知識庫 增強日志分析,根因分析能力的技術方案(2):LangChain + LlamaIndex 實現

                  文章大綱 1 技術原理總覽 2 詳細實現步驟(含代碼) 2.1 環境準備 2.2 Excel → LlamaIndex 節點 2.3 構建向量索引(FAISS 本地) 2.4 Google Cloud 向量檢索(可選替換 FAISS) 2.5 LangChain 問答鏈 A. RAG 模式(向量檢索 + LLM 生成) B. SQL 模式(無 RAG,直接查表) 2.…

                  提升ARM Cortex-M系統性能的關鍵技術:TCM技術解析與實戰指南

                  文章目錄引言一、TCM基礎架構與工作原理1.1 TCM的物理特性1.2 與緩存機制的對比1.3 ARM Cortex-M系列對TCM的支持二、TCM的典型應用場景2.1 實時中斷處理2.2 低功耗模式下的待機代碼2.3 高性能算法執行2.4 系統初始化階段的關鍵代碼三、實戰指南&#xff1a;在STM32H7上配置和優…

                  大數據之路:阿里巴巴大數據實踐——大數據領域建模綜述

                  為什么需要數據建模 核心痛點 數據冗余&#xff1a;不同業務重復存儲相同數據&#xff08;如用戶基礎信息&#xff09;&#xff0c;導致存儲成本激增。計算資源浪費&#xff1a;未經聚合的明細數據直接參與計算&#xff08;如全表掃描&#xff09;&#xff0c;消耗大量CPU/內存…

                  實戰演練1:實戰演練之命名實體識別

                  實戰演練1:實戰演練之命名實體識別 命名實體識別簡介 代碼 命名實體識別簡介 什么是命名實體識別任務 命名實體識別(Named Entity Recognition,簡稱NER)是指識別文本中具有特定意義的實體,主要包括人名、地名、機構名、專有名詞等。通常包括兩部分: (1)實體邊界識別。(2)確定…

                  數據結構基礎內容(第七篇:堆、哈夫曼樹)

                  # 堆 Heap 優先隊列(Priority Queue) 結構性:用 *數組* 表示的完全二叉樹; 有序性:任一結點的關鍵字是其子樹所有結點的最大值(或最小值) * “最大堆(MaxHeap)”,也稱“大頂堆”:最大值 * “最小堆(MinHeap)”,也稱“小頂堆” :最小值 主要操作有: ? MaxHeap Create( i…

                  CS231n-2017 Lecture7訓練神經網絡(二)筆記

                  本節主要是神經網絡的動態部分&#xff0c;也就是神經網絡學習參數和搜索最優超參數的過程梯度檢查&#xff1a;進行梯度檢查&#xff0c;就是簡單地把解析梯度與數值計算梯度進行比較&#xff0c;防止反向傳播的邏輯出錯&#xff0c;僅在調試過程中使用。有如下技巧 &#xff…

                  IntelliJ IDEA 中左上方未顯示項目根目錄問題

                  問題&#xff1a; 在IDEA中編寫代碼時&#xff0c;發現左上方只顯示項目的子模塊&#xff0c;未顯示根項目名稱。 如圖所示&#xff0c;未顯示子模塊的根項目&#xff1a;問題分析 頂層根目錄未被識別為項目根目錄&#xff0c;需要手動添加識別。 問題解決 進入File – Project…

                  OpenCV 圖像變換全解析:從鏡像翻轉到仿射變換的實踐指南

                  前言處理圖像時&#xff0c;翻轉、旋轉、平移等操作很常用。OpenCV 提供了簡單的方法實現這些變換&#xff0c;本文帶你快速學會用它做圖像翻轉和仿射變換。1 圖像翻轉(圖像鏡像旋轉)在OpenCV中&#xff0c;圖片的鏡像旋轉是以圖像的中心為原點進行鏡像翻轉的。cv2.flip(img,fl…

                  【運維】Linux運維命令記錄

                  重置root密碼使用命令重新設置一下root賬戶的密碼 passwd root根據提示設置一下密碼&#xff0c;然后使用sudo -i 時輸入密碼就可以切換到root賬戶了ssh登陸以后&#xff0c;要用sudo -i命令給用戶提權&#xff0c;提到超級管理員&#xff0c;然后輸入密碼才有用

                  PandasAI連接LLM進行智能數據分析

                  1. 引言 Pandas是一個數據分析開源組件庫&#xff0c;提供了高性能、易用的數據結構和數據分析工具。它的核心的功能是其DataFrame對象&#xff0c;這是一個帶有行和列標簽的二維表格數據結構&#xff0c;支持缺失數據處理、時間序列功能、靈活的數據輸入輸出方法、數據對齊和…

                  Spring之【Bean的生命周期】

                  目錄 1、生成BeanDefinition BeanDefinitionRegistry接口 DefaultListableBeanFactory實現類 2、合并BeanDefnition AbstractBeanFactory類 3、BeanFactoryPostProcessor的方法回調 AbstractApplicationContext類 PostProcessorRegistrationDelegate類 4、BeanPostPro…

                  搜狐新聞直播間適配HarmonyOs實現點贊動畫

                  01背景介紹隨著新聞客戶端鴻蒙單框架系統適配工作的推進&#xff0c;從原來的基礎功能到現在已經適配全功能的85%以上。與此同時&#xff0c;我們也在持續深入挖掘鴻蒙系統的特性&#xff0c;以提升整體應用的質量與用戶體驗。在這一過程中&#xff0c;動畫作為增強交互與視覺體…

                  83、設置有人DTU設備USR-M100采集傳感器數據,然后上傳阿里云服務

                  基本思想:設置M100 采集傳感器數據 一、首先將DTU設備USR-M100連接路由器上,然后使用python代碼搜索同一局域網設備, import platform import sys import os import time import threadinglive_ip = 0def get_os():os = platform.system()if os == "Windows":re…

                  P1019 [NOIP 2000 提高組] 單詞接龍

                  題目描述單詞接龍是一個與我們經常玩的成語接龍相類似的游戲&#xff0c;現在我們已知一組單詞&#xff0c;且給定一個開頭的字母&#xff0c;要求出以這個字母開頭的最長的“龍”&#xff08;每個單詞都最多在“龍”中出現兩次&#xff09;&#xff0c;在兩個單詞相連時&#…

                  詳解力扣高頻SQL50題之1633. 各賽事的用戶注冊率【簡單】

                  傳送門&#xff1a;1633. 各賽事的用戶注冊率 題目 用戶表&#xff1a; Users -------------------- | Column Name | Type | -------------------- | user_id | int | | user_name | varchar | -------------------- user_id 是該表的主鍵(具有唯一值的列)。 該表中的每行包…

                  FROM stakater/java8-alpine 構建cocker鏡像

                  在 Dockerfile 中&#xff0c;FROM stakater/java8-alpine 是第一條也是最核心的指令&#xff0c;它定義了構建新鏡像所基于的「基礎鏡像」。以下是逐層解析&#xff1a;&#x1f50d; 關鍵字拆解 1. FROM —— 起點指令 ? 作用&#xff1a;聲明當前鏡像的起點&#xff08;父鏡…

                  Word2Vec模型訓練全流程解析:從數據預處理到實體識別應用

                  請添加圖片描述 訓練Word2Vec模型 概述 問題 我們如何訓練Word2Vec模型&#xff1f;在特定數據集上訓練Word2Vec模型何時是有利的&#xff1f; 目標 理解在自有數據上訓練Word2Vec模型而非使用預訓練模型的優勢 Colab環境配置 運行以下代碼以啟用輔助函數并重新讀取數據…

                  在Ubuntu上使用QEMU學習RISC-V程序(2)gdb調試

                  文章目錄一、準備工作二、基本調試流程1. 設置斷點2. 執行程序3. 查看源代碼/匯編三、查看寄存器1. 查看通用寄存器2. 查看特殊寄存器四、查看內存1. 內存查看命令2. 內存修改命令五、調試實戰示例六、高級調試技巧1. 條件斷點2. 自動顯示3. 內存斷點&#xff08;觀察點&#x…

                  不止于“亮”:一盞智慧路燈的技術進化史——塔能科技用“落地性”定義行業標準

                  在凌晨3點的園區道路之上&#xff0c;路燈會隨著車輛的靠近而自動亮起&#xff0c;待車輛逐漸遠去之后&#xff0c;又會緩緩地調暗下來&#xff1b;當電纜意外被觸碰的時候&#xff0c;系統能夠在短短3秒之內自動發出報警信息&#xff0c;并且推送出維修工單&#xff1b;而當一…

                  Redis的String數據類型底層實現

                  redis就是用c語言寫&#xff0c;但redis的string并沒有直接用c語言的string&#xff0c;而是自己搞了一個 SDS 結構體來表示字符串。SDS 的全稱是 Simple Dynamic String&#xff0c;中文叫做“簡單動態字符串”。想知道為什么這么做&#xff0c;我們先看看c語言的string是什么…