日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > C# >内容正文

C#

C#调用C/C++ DLL的相关说明

發(fā)布時間:2025/4/5 C# 51 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C#调用C/C++ DLL的相关说明 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

C# 調(diào)用DLL 常用如下方式來引用庫中的函數(shù) (當(dāng)然還有很多其它的實(shí)現(xiàn)方式,這里就不多講),本文主要講要使用中遇到的常見問題:

一,庫的引用 加上 :using System.Runtime.InteropServices;

[DllImport("XXX")]
static extern void UbtServoGroupInit(ref UbtUartServo Sgroup, pwrite write, pread read);

上面有注意的有兩點(diǎn):

1,XXX 可以是DLL庫名不帶.dll 后輟,也可以是全名

2,函數(shù)前的 static extern 是一定要加的

?

二,DLL頭文件實(shí)現(xiàn)

C#中沒有.H文件,如果DLL中用到了一些頭文件(里面有結(jié)構(gòu)體等自定義類型),需在要C#環(huán)境中從新定義,這里會有各種變量的對應(yīng)轉(zhuǎn)換關(guān)系:

/****** 以下內(nèi)容引自于https://www.cnblogs.com/zhaoxinshanwei/p/4008627.html? ***********/

//c++:HANDLE(void???*)???????----???c#:System.IntPtr????????
//c++:Byte(unsigned???char)???----????c#:System.Byte?????????
//c++:SHORT(short)???????????----????c#:System.Int16?????????
//c++:WORD(unsigned?short)?---??c#:System.UInt16????????
//c++:INT(int)?????????????????----????c#:System.Int16????????
//c++:INT(int)??????????????????----????c#:System.Int32?????????
//c++:UINT(unsigned?int)??----????c#:System.UInt16????????
//c++:UINT(unsigned?int)?----????c#:System.UInt32????????
//c++:LONG(long)?????????????----????c#:System.Int32?????????
//c++:ULONG(unsigned?long)?--???c#:System.UInt32?????????
//c++:DWORD(unsigned?long)?--??c#:System.UInt32?????????
//c++:DECIMAL?????????----????c#:System.Decimal?????????
//c++:BOOL(long)????????----????c#:System.Boolean?????????
//c++:CHAR(char)???????----????c#:System.Char??
???????
//c++:LPSTR(char?*)??????----????c#:System.String?????????
//c++:LPWSTR(wchar_t?*)??----????c#:System.String?????????
//c++:LPCSTR(const?char?*)??---???c#:System.String?????????
//c++:LPCWSTR(const?wchar_t?*)?---???c#:System.String?????????

//c++:PCAHR(char?*)???----???c#:System.String?????
????
//c++:BSTR???????----????c#:System.String???????
??
//c++:FLOAT(float)??????----????c#:System.Single?????????
//c++:DOUBLE(double)????----????c#:System.Double?????????
//c++:VARIANT???????????----????c#:System.Object?????????
//c++:PBYTE(byte???*)???----????c#:System.Byte[]?????????
//c++:BSTR??????----????c#:StringBuilder????
????
//c++:LPCTSTR???----????c#:StringBuilder??
??????
//c++:LPCTSTR???----????c#:string????????

//c++:LPTSTR????----????
c#:[MarshalAs(UnmanagedType.LPTStr)]?string??
???????
//c++:LPTSTR?????----????c#:StringBuilder?
?????
//c++:LPCWSTR???----????c#:IntPtr????????

//c++:BOOL??????----????c#:bool???????????

//c++:HMODULE???----????c#:IntPtr????????
????
//c++:HINSTANCE?----????c#:IntPtr????????
?
//c++:結(jié)構(gòu)體????----????c#:public?struct?結(jié)構(gòu)體{};?
????????
//c++:結(jié)構(gòu)體?**變量名???----????c#:out?變量名???

//C#中提前申明一個結(jié)構(gòu)體實(shí)例化后的變量名??????
?
//c++:結(jié)構(gòu)體?&變量名????----????c#:ref?結(jié)構(gòu)體?變量名?????????????????
//c++:WORD??????----????c#:ushort????????

//c++:DWORD?????----????c#:uint????????

//c++:DWORD?????----????c#:int????????

//c++:UCHAR?????----????c#:int????????

//c++:UCHAR?????----????c#:byte????????

//c++:UCHAR*????----????c#:string??????
??
//c++:UCHAR*????----????c#:IntPtr????????

//c++:GUID??????----????c#:Guid????????

//c++:Handle????----????c#:IntPtr????????

//c++:HWND??????----????c#:IntPtr????????

//c++:DWORD?????----????c#:int????????

//c++:COLORREF??----????c#:uint???????
?
//c++:unsigned?char?????----????c#:byte??????
??
//c++:unsigned?char?*???----????c#:ref?byte???????
?
//c++:unsigned?char?*???----????
c#:[MarshalAs(UnmanagedType.LPArray)]?byte[]????????
//c++:unsigned?char?*???----????
c#:[MarshalAs(UnmanagedType.LPArray)]?Intptr????????
//c++:unsigned?char?&???----????c#:ref?byte??
??????
//c++:unsigned?char?變量名??????----????c#:byte?變量名????????
//c++:unsigned?short?變量名????----???c#:ushort?變量名????????
//c++:unsigned?int?變量名???????----????c#:uint?變量名????????
//c++:unsigned?long?變量名?????----????c#:ulong?變量名????????
//c++:char?變量名???????----????c#:byte?變量名?
??
//c++中一個字符用一個字節(jié)表示,c#中一個字符用兩個字節(jié)表示????????

//c++:char?數(shù)組名[數(shù)組大小]?????----????
c#:MarshalAs(UnmanagedType.ByValTStr,?SizeConst?=?數(shù)組大小)]????????
???
//c++:char?*????????????----????c#:string???????
?
//c++:char?*????????????----????c#:StringBuilder
????
//c++:char?*變量名??????----????c#:ref?string?變量名????????
//c++:char?*輸入變量名??----????c#:string?輸入變量名????????
//c++:char?*輸出變量名??----????
c#:[MarshalAs(UnmanagedType.LPStr)]?StringBuilder?輸出變量名??????
??
//c++:char?**???????????----????c#:string?????
???
//c++:char?**變量名?????----????c#:ref?string?變量名????????
//c++:const?char?*??????----????c#:string???
?????
//c++:char[]????????????----????c#:string?????
???
//c++:char?變量名[數(shù)組大小]?????----????
c#:[MarshalAs(UnmanagedType.ByValTStr,SizeConst=數(shù)組大小)]?public?string?變量名;?????

//c++:struct?結(jié)構(gòu)體名?*變量名???----????c#:ref?結(jié)構(gòu)體名?變量名????????

//c++:委托?變量名???----????c#:委托?變量名????
????
//c++:int???????----????c#:int????????

//c++:int???????----????c#:ref?int????????

//c++:int?&?????----????c#:ref?int??????
??
//c++:int?*?????----????c#:ref?int??????

//C#中調(diào)用前需定義int?變量名?=?0;??????
??
//c++:*int??????----????c#:IntPtr????????

//c++:int32?PIPTR?*?????----????c#:int32[]???
?????
//c++:float?PIPTR?*?????----????c#:float[]???????
?????????
//c++:double**?數(shù)組名??????????----????c#:ref?double?數(shù)組名????????

//c++:double*[]?數(shù)組名??????????----????c#:ref?double?數(shù)組名????????

//c++:long??????????----????c#:int????????

//c++:ulong?????????----????c#:int???????????
?????
//c++:UINT8?*???????----????c#:ref?byte??????
?
//C#中調(diào)用前需定義byte?變量名?=?new?byte();????????????????
//c++:handle????----????c#:IntPtr????????

//c++:hwnd??????----????c#:IntPtr?????????
???????????????
//c++:void?*????----????c#:IntPtr??????????
??????
//c++:void?*?user_obj_param????----????
c#:IntPtr?user_obj_param????????

//c++:void?*?對象名稱????----????
c#:([MarshalAs(UnmanagedType.AsAny)]Object?對象名稱????????????????

//c++:char,INT8,SBYTE,CHAR??--??c#:System.SByte??????????
//c++:short,?short?int,?INT16,?SHORT????????????????????????----????c#:System.Int16????????
??
//c++:int,?long,?long?int,INT32,?LONG32,?BOOL?,?INT??----????c#:System.Int32???????
???
//c++:__int64,INT64,LONGLONG???????????????????????????--??c#:System.Int64??????????

//c++:unsigned?char,?UINT8,?UCHAR?,?BYTE???????????????----????c#:System.Byte??????????

//c++:unsigned?short,?UINT16,?USHORT,?WORD,?ATOM,?WCHAR?,?__wchar_t??----??c#:System.UInt16??????????

//c++:unsigned,?unsigned?int,?UINT32,?ULONG32,?DWORD32,?ULONG,?DWORD,?UINT?????
?----????c#:System.UInt32??????????

//c++:unsigned?__int64,?UINT64,?DWORDLONG,?ULONGLONG????????????????????????????
----????c#:System.UInt64??????????

//c++:float,FLOAT????--??c#:System.Single??????????

//c++:double,?long?double,?DOUBLE??????????????????????????----????c#:System.Double??????????

//Win32?Types????????----??CLR?Type???????
???????????
//Struct需要在C#里重新定義一個Struct????
????
//CallBack回調(diào)函數(shù)需要封裝在一個委托里,delegate?static?extern?int?FunCallBack(string?str);???????
?
//unsigned?char**?ppImage替換成IntPtr?ppImage????????
//int&?nWidth替換成ref?int?nWidth???????
?
//int*,?int&,?則都可用?ref?int?對應(yīng)??????
??
//雙針指類型參數(shù),可以用?ref?IntPtr???????
?
//函數(shù)指針使用c++:?typedef?double?(*fun_type1)(double);?對應(yīng)?c#:public?delegate?double??fun_type1(double);????????

//char*?的操作c++:?char*;?對應(yīng)?c#:StringBuilder;????????
//c#中使用指針:在需要使用指針的地方?加?unsafe????????

//unsigned???char對應(yīng)public???byte???

/****** 以上內(nèi)容引自于https://www.cnblogs.com/zhaoxinshanwei/p/4008627.html? ***********/

根據(jù)上面的對應(yīng)關(guān)系重新實(shí)現(xiàn)結(jié)構(gòu)體或自定義類型,如:

public enum Status
? ? {
? ? ? ? Servo_OK = 0,
? ? ? ? Servo_TimeOut,
? ? ? ? Servo_ParErr,
? ? ? ? Servo_LibInitErr,
? ? ? ? Servo_TemperatureLow,
? ? ? ? Servo_TemperatureHight,
? ? ? ? Servo_VoltageLow,
? ? ? ? Servo_VoltageHight,
? ? ? ? Servo_CurrentOver,
? ? ? ? Servo_TorqueOver,
? ? ? ? Servo_FuseErr,
? ? ? ? Servo_PwmErr,
? ? ? ? Servo_CmdFail,
? ? ? ? Servo_ReciveErr,
? ? };

? ?public struct UbtUartServo
? ? {
? ? ? ? [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
? ? ? ? ?string RxBuf;

? ? ? ? //1.定義回調(diào)函數(shù)指針.
? ? ? ? public pwrite write;
? ? ? ? public pread read;
? ? };

三,C#中如何實(shí)現(xiàn)類似于函數(shù)指針功能 (delegate)委托:

C/C++中的 typedef void (*pwrite)Byte buf, Byte size);

在C#可對應(yīng)為:delegate ?void pwrite(ref Byte buf, Byte size);

如 在 C 中

typedef struct?
{
?? ?uint8_t RxBuf[64];
?? ?void ? (*pwrite)(uint8_t *buf,uint8_t size) ? ? C51;
?? ?uint8_t ? (*pread)(uint8_t *buf,uint8_t size,uint8_t mstimeout) ?C51;
} UbtUartServo;

在C#的實(shí)現(xiàn)為:

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
? ? public delegate ?void pwrite(ref Byte buf, Byte size);

? ? [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
? ? public delegate ?Byte pread(ref Byte buf, Byte size, Byte mstimeout);
? ? ?

? ? public struct UbtUartServo
? ? {
? ? ? ? [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
? ? ? ? ?string RxBuf;

? ? ? ? //1.定義回調(diào)函數(shù)指針.
? ? ? ? public pwrite write;
? ? ? ? public pread read;
? ? };

其中上面的,Cdecl說明DLL是C格式!

C++或其它可能要用不同的格式(前三個用的多一些,不過不行可以試度其它):

namespace System.Runtime.InteropServices
{
? ? [Serializable]
? ? [ComVisible(true)]
? ? public enum CallingConvention
? ? {
? ? ? ? Winapi = 1,
? ? ? ? Cdecl = 2,
? ? ? ? StdCall = 3,

? ? ? ? ThisCall = 4,
? ? ? ? FastCall = 5,
? ? }
}

不然有可能會出現(xiàn) 如下錯誤:

The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.?
?

? [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
? ? public delegate ?void pwrite(ref Byte buf, Byte size);

?

四,給個例子:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace CshareServoTest
{


? ? public enum Status
? ? {
? ? ? ? Servo_OK = 0,
? ? ? ? Servo_TimeOut,
? ? ? ? Servo_ParErr,
? ? ? ? Servo_LibInitErr,
? ? ? ? Servo_TemperatureLow,
? ? ? ? Servo_TemperatureHight,
? ? ? ? Servo_VoltageLow,
? ? ? ? Servo_VoltageHight,
? ? ? ? Servo_CurrentOver,
? ? ? ? Servo_TorqueOver,
? ? ? ? Servo_FuseErr,
? ? ? ? Servo_PwmErr,
? ? ? ? Servo_CmdFail,
? ? ? ? Servo_ReciveErr,
? ? };

? ? [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
? ? public delegate ?void pwrite(ref Byte buf, Byte size);

? ? [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
? ? public delegate ?Byte pread(ref Byte buf, Byte size, Byte mstimeout);
? ? ?

? ? public struct UbtUartServo
? ? {
? ? ? ? [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
? ? ? ? ?string RxBuf;

? ? ? ? //1.定義回調(diào)函數(shù)指針.
? ? ? ? public pwrite write;
? ? ? ? public pread read;
? ? };


? ? public partial class Form1 : Form
? ? {
? ? ? ? [DllImport("ServoLibDll")]
? ? ? ? static extern void UbtServoGroupInit(ref UbtUartServo Sgroup, pwrite write, pread read);

? ? ? ? [DllImport("ServoLibDll")]
? ? ? ? static extern Status UbtServoMove(ref UbtUartServo Sgroup, Byte ServoID, Byte TargetAngle, Int16 RunTime, UInt16 KeepTime, Byte BackTimeOut);

? ? ? ? public UbtUartServo Test;

? ? ? ? public Form1()
? ? ? ? {
? ? ? ? ? ? InitializeComponent();
? ? ? ? ? ? Test = new UbtUartServo();

? ? ? ? ? ? //Test.write = new pwrite(write);
? ? ? ? ? ? //Test.read = new pread(read);

? ? ? ? ? ? UbtServoGroupInit(ref Test, new pwrite(this.write), new pread(this.read));
? ? ? ? }

? ? ? ? private void TestButton_Click(object sender, EventArgs e)
? ? ? ? {
? ? ? ? ? ? UbtServoMove(ref Test, 0, 120, 25, 500, 50);
? ? ? ? }

? ? ? ? public void write(ref Byte buf, Byte size)
? ? ? ? {
? ? ? ? ? ? ServoTest.Text = "write";
? ? ? ? ? ? return;
? ? ? ? }

? ? ? ? public Byte read(ref Byte buf, Byte size, Byte mstimeout)
? ? ? ? {
? ? ? ? ? ? ServoTest.Text = "read";
? ? ? ? ? ? return 1;
? ? ? ? }


? ? }
}
?

?

?

?

?

總結(jié)

以上是生活随笔為你收集整理的C#调用C/C++ DLL的相关说明的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。