国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > C++ > 正文

C#調用C++DLL

2019-11-08 01:26:23
字體:
來源:轉載
供稿:網友

   在合作開發時,C#時常需要調用C++DLL。研究了一下C#,發現其強大簡潔, 在跨語言調用方面封裝的很徹底,提供了強大的API與之交互.這點比JNA方便多了. java與C#都只能調用C格式導出動態庫,因為C數據類型比較單一,容易映射. 兩者都是在本地端提供一套與之映射的C#/java描述接口,通過底層處理這種映射關系達到調用的目的.

1、調用例子(例子中提供了傳值調用和傳址調用兩種方法):

C++代碼(C++生成動態庫DLL.dll):

Lib.h

//文件:lib.h#PRagma once#include <string> using namespace std;  #define JNAAPI extern "C" __declspec(dllexport) // C方式導出函數typedef struct CARDINFO{	int majorVersion;	int minorVersion;	int cardType;	char szDescribe[128];};// 1. 獲取版本信息(傳遞結構體指針)    JNAAPI bool GetVersionPtr(CARDINFO *info);// 2.獲取版本信息(傳遞結構體引用)    JNAAPI bool GetVersionRef(CARDINFO &info);

Lib.cpp

#include "stdafx.h"#include "lib.h"#include <stdlib.h>using namespace std;// 1. 獲取版本信息(傳遞結構體指針)    bool GetVersionPtr(CARDINFO *info){	info->majorVersion = 1;	info->minorVersion = 22;	info->cardType = 3;	memcpy(info->szDescribe, "hello world", 128);	return true;}// 2.獲取版本信息(傳遞結構體引用)    bool GetVersionRef(CARDINFO &info){	info.majorVersion = 1;	info.minorVersion = 22;	info.cardType = 3;	memcpy(info.szDescribe, "hello world", 128);	return true;}

C#代碼(C++生成動態庫DLL.dll):

class CCommand{    const string dllpathfile = "..//..//..//..//Lib//DLL.dll";    // CARDINFO定義      [StructLayout(LayoutKind.Sequential)]    public struct CARDINFO    {        public int majorVersion;        public int minorVersion;        public int cardType;        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]        public string szDescribe;    }    [DllImport(dllpathfile, EntryPoint = "GetVersionPtr")]    public static extern bool GetVersionPtr(ref CARDINFO info);    [DllImport(dllpathfile, EntryPoint = "GetVersionRef")]    public static extern bool GetVersionRef(ref CARDINFO info);}	調用:

   //C#調用C++庫   CCommand.CARDINFO cardInfo = new CCommand.CARDINFO();   CCommand.GetVersionPtr(ref cardInfo);

2、類型轉換說明:

類型對照:

C++類型

C#類型

BSTR

StringBuilder

LPCTSTR

StringBuilder

LPCWSTR

IntPtr

handle

IntPtr

hwnd

IntPtr

char *

string

int *

ref int

int &

ref int

void *

IntPtr

unsigned char *

ref byte

CLR Type

Win32 Types

System.SByte

char, INT8, SBYTE, CHAR

System.Int16

short, short int, INT16, SHORT

System.Int32

int, long, long int, INT32, LONG32, BOOL , INT

System.Int64

__int64, INT64, LONGLONG

System.Byte

unsigned char, UINT8, UCHAR , BYTE

System.UInt16

unsigned short, UINT16, USHORT, Word, ATOM, WCHAR , __wchar_t

System.UInt32

unsigned, unsigned int,

UINT32, ULONG32, DWORD32, ULONG, DWORD, UINT

System.UInt64

unsigned __int64,

UINT64, DWORDLONG, ULONGLONG

System.Single

float, FLOAT

System.Double

double, long double, DOUBLE

注:

C#中類型轉換接口:

將string轉為IntPtr:

IntPtrSystem.Runtime.InteropServices.Marshal.StringToCoTaskMemAuto(string)

 

將IntPtr轉為string:

stringSystem.Runtime.InteropServices.MarshalPtrToStringAuto(IntPtr)

3、代碼分析

C#為了用上C++的代碼,只好研究下從C# 中調用DLL,首先必須要有一個聲明,使用的是DllImport關鍵字,包含DllImport所在的名字空間

using System.Runtime.InteropServices;class CCommand{    conststringdllpathfile ="..//..//..//..//Lib//DLL.dll";    [DllImport(dllpathfile, EntryPoint ="GetVersionPtr")]    publicstaticexternboolGetVersionPtr(refCARDINFOinfo);}

DllImport關鍵字作用是告訴編譯器入口點在哪里,并將打包函數捆綁在這個類中,在類中,直接調用GetVersionPtr,在其他的類中調用CCommand.GetVersionPtr

[DllImport(dllpathfile)]在申明的時候還可以添加幾個屬性[DllImport(dllpathfile, EntryPoint="GetVersionPtr ",CharSet=CharSet.Auto,CallingConvention=CallingConvention.StdCall)]EntryPoint: 指定要調用的 DLL 入口點。默認入口點名稱是托管方法的名稱 。CharSet: 控制名稱重整和封送 String 參數的方式 (默認是UNICODE)CallingConvention指示入口點的函數調用約定(默認WINAPI) SetLastError 指示被調用方在從屬性化方法返回之前是否調用 SetLastError Win32 API 函數 (C#中默認false )


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

主站蜘蛛池模板: 闸北区| 武功县| 馆陶县| 石河子市| 仙桃市| 中牟县| 怀远县| 兴仁县| 太谷县| 泽普县| 五常市| 托克托县| 安溪县| 凤凰县| 嵊泗县| 公主岭市| 金华市| 手机| 嘉峪关市| 民丰县| 五莲县| 玛曲县| 额济纳旗| 库车县| 太仆寺旗| 黔南| 霍林郭勒市| 泰顺县| 宁国市| 淮北市| 肥乡县| 吴忠市| 巴马| 高雄市| 襄汾县| 阿坝县| 历史| 远安县| 黄冈市| 弋阳县| 孟津县|