91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C#中調用C類型dll入參為struct的問題分析

發布時間:2021-03-22 10:47:36 來源:億速云 閱讀:429 作者:小新 欄目:開發技術

這篇文章將為大家詳細講解有關C#中調用C類型dll入參為struct的問題分析,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

前言

C# 可以通過 DllImport 的方式引用 C 類型的 dll。但很多 dll 的參數不會是簡單的基礎類型,而是結構體 struct 。因此就需要在 C# 端定義同樣的結構體類型,才能實現調用 C 類型 dll。這里例舉幾種不同的結構體情況,以及其對應的解決方案。

基礎調用方式

對于一個結構體類型:

typedef struct DATA
{
  int nNumber;
  float fDecimal;
};

在 C# 端就需要定義為

[StructLayout(LayoutKind.Sequential)]
public struct DATA
{
  public int nNumber;
  public float fDecimal;
}

包含字符數組

對于一個包含字符數組的結構體類型:

typedef struct DATA
{
  int nNumber;
  float fDecimal;
  char szString[256];
};

在 C# 端就需要使用 Marshal 設置數據空間大小,同時最好定義一個初始化函數與 get 的定義

[StructLayout(LayoutKind.Sequential)]
public struct DATA
{
  void alloc() {
    szString = new char[256];
  }

  string sString {
    get {
      int nLength = 256;
      string sData = "";
      for (int i = 0; i < nLength; i++)
      {
        if (szData[i] == '\0') break;
        sData += szData[i];
      }
      return sData;
    }
  }

  public int nNumber;
  public float fDecimal;
  [MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)]
  char[] szString;
}

包含字符二維數組

對于一個包含字符二維數組的結構體類型:

typedef struct DATA
{
  int nNumber;
  float fDecimal;
  char szString[6][256];
};

在 C# 端同樣需要使用 Marshal 設置數據空間大小,需要將兩個 Size 相乘,并定義一個初始化函數。同時在做一個 get 的定義。

[StructLayout(LayoutKind.Sequential)]
public struct DATA
{
  void alloc() {
    szString = new char[256 * 6];
  }

  public string[] sStrings
  {
    get {
      int nSize = 6, nLength = 256;
      string[] sDatas = new string[nSize];
      for (int i = 0; i < nSize; i++)
      {
        for (int j = 0; j < nLength; j++)
        {
          if (szData[i * nLength + j] == '\0') break;
          sData += szData[i * nLength + i];
        }
        sDatas[i] = sData;
      }
      return sDatas;
    }
  }

  public int nNumber;
  public float fDecimal;
  [MarshalAs(UnmanagedType.ByValArray, SizeConst = 256 * 6)]
  char[] szStrings;
}

dll 入參為結構體數組

若有一個這樣的 C dll 函數定義:

void FnCall(DATA* datas);

// 調用方式
DATA datas[10];
fnCall(datas);

那么,在 C# 中要實現等價調用:

// 首先 Import 函數
[DllImport("Module.dll")]
public static extern void FnCall(IntPtr pInfo); // 注意入參要定義為指針

// 再定義定義結構體數組
int nCount = 10;
DATA datas = new DATA[nCount];

// 再分配內存空間
int nSize = Marshal.SizeOf(typeof(DEVICE_INFO));
IntPtr Dataptr = Marshal.AllocHGlobal(nSize * nCount);

// 調用函數
FnCall(Dataptr);

// 復制數據到結構體中
for (int i = 0; i < nCount; i++)
{
  IntPtr ptr = (IntPtr)((UInt32)Dataptr + i * size);
  datas[i] = (DEVICE_INFO)Marshal.PtrToStructure(ptr, typeof(DEVICE_INFO));
}

// 釋放內存空間
Marshal.FreeHGlobal(Dataptr);

另外,如果你要調用的 dll 是非 C 類型 dll,而是 C++ Class。那么我們就可以將其再包裝一層,轉換為 C 類型 dll。

例如:

class Example {
public:
 int MethodCall();
};

那么就可以編寫 C 類型的 dll。

extern "C" {
  Example* Example_New() { 
    return new Example(); 
  }
  int Example_MethodCall(Example* p) { 
    return p->MethodCall(); 
  }
  void Example_Delete(Example* p) { 
    delete p; 
  }
}

C# 那邊就這樣導入

[DllImport("Module.dll")]
public static extern IntPtr Example_Create();

[DllImport("Module.dll")]
public static extern int Example_MethodCall(IntPtr value);

[DllImport("Module.dll")]
public static extern void Example_Delete(IntPtr value);

// 調用方式
IntPtr p = Example_Create();
Example_MethodCall(p);
Example_Delete(p);

關于“C#中調用C類型dll入參為struct的問題分析”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

石林| 宜兴市| 义乌市| 竹溪县| 韶山市| 北票市| 渭源县| 郯城县| 仲巴县| 来安县| 乐都县| 兴城市| 清丰县| 天祝| 崇阳县| 呼伦贝尔市| 双峰县| 留坝县| 涟水县| 招远市| 南溪县| 哈巴河县| 敦化市| 怀远县| 正定县| 和硕县| 彭州市| 海伦市| 攀枝花市| 武夷山市| 库车县| 抚远县| 县级市| 根河市| 江永县| 额尔古纳市| 梁平县| 凤山市| 大同县| 商水县| 梧州市|