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

首頁 > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

C#調(diào)用C/C++動(dòng)態(tài)庫 封送結(jié)構(gòu)體,結(jié)構(gòu)體數(shù)組

2019-11-17 03:06:25
字體:
供稿:網(wǎng)友
C#調(diào)用C/C++動(dòng)態(tài)庫 封送結(jié)構(gòu)體,結(jié)構(gòu)體數(shù)組

因?yàn)楣疽恢倍际亲鯟++開發(fā)的,因客戶需要要提供C#版本接口,研究了一下C#,發(fā)現(xiàn)其強(qiáng)大簡(jiǎn)潔, 在跨語言調(diào)用方面封裝的很徹底,提供了強(qiáng)大的API與之交互.這點(diǎn)比JNA方便多了. java與C#都只能調(diào)用C格式導(dǎo)出動(dòng)態(tài)庫,因?yàn)镃數(shù)據(jù)類型比較單一,容易映射. 兩者都是在本地端提供一套與之映射的C#/java描述接口,通過底層處理這種映射關(guān)系達(dá)到調(diào)用的目的.

一.結(jié)構(gòu)體的傳遞

Cpp代碼收藏代碼
  1. #defineJNAAPIextern"C"__declspec(dllexport)//C方式導(dǎo)出函數(shù)
  2. typedefstruct
  3. {
  4. intosVersion;
  5. intmajorVersion;
  6. intminorVersion;
  7. intbuildNum;
  8. intplatFormId;
  9. charszVersion[128];
  10. }OSINFO;
  11. //1.獲取版本信息(傳遞結(jié)構(gòu)體指針)
  12. JNAAPIboolGetVersionPtr(OSINFO*info);
  13. //2.獲取版本信息(傳遞結(jié)構(gòu)體引用)
  14. JNAAPIboolGetVersionRef(OSINFO&info);

可以通過二種方式來調(diào)用:

C#代碼收藏代碼
  1. //OSINFO定義
  2. [StructLayout(LayoutKind.Sequential)]
  3. publicstructOSINFO
  4. {
  5. publicintosVersion;
  6. publicintmajorVersion;
  7. publicintminorVersion;
  8. publicintbuildNum;
  9. publicintplatFormId;
  10. [MarshalAs(UnmanagedType.ByValTStr,SizeConst=128)]
  11. publicstringszVersion;
  12. }

1. 方式一(傳入結(jié)構(gòu)體引用),在C#中,結(jié)構(gòu)體是以傳值方式傳遞,類才是以傳地址方式傳遞,加關(guān)鍵字ref即可. C端傳遞了兩種不同類型的參數(shù),都可以通過引用來解決.

C#代碼收藏代碼
  1. [DllImport("jnalib.dll",EntryPoint="GetVersionPtr")]
  2. publicstaticexternboolGetVersionPtr(refOSINFOinfo);
  3. publicstaticexternboolGetVersionRef(refOSINFOinfo);

2. 方式二(傳入IntPtr(平臺(tái)通用指針))

Cpp代碼收藏代碼
  1. IntPtrpv=Marshal.AllocHGlobal(148);//結(jié)構(gòu)體在使用時(shí)一定要分配空間(4*sizeof(int)+128)
  2. Marshal.WriteInt32(pv,148);//向內(nèi)存塊里寫入數(shù)值
  3. if(GetVersionPtr(pv))//直接以非托管內(nèi)存塊地址為參數(shù)
  4. {
  5. Console.WriteLine("--osVersion:{0}",Marshal.ReadInt32(pv,0));
  6. Console.WriteLine("--Major:{0}",Marshal.ReadInt32(pv,4));//移動(dòng)4個(gè)字節(jié)
  7. Console.WriteLine("--BuildNum:"+Marshal.ReadInt32(pv,12));
  8. Console.WriteLine("--szVersion:"+Marshal.PtrToStringAnsi((IntPtr)(pv.ToInt32()+20)));
  9. }
  10. Marshal.FreeHGlobal(pv);//處理完記得釋放內(nèi)存

二.結(jié)構(gòu)體數(shù)組的傳遞

Cpp代碼收藏代碼
  1. //傳遞結(jié)構(gòu)體指針
  2. JNAAPIboolGetVersionArray(OSINFO*info,intnLen);

調(diào)用代碼:

C#代碼收藏代碼
  1. /**
  2. *C#接口,對(duì)于包含數(shù)組類型,只能傳遞IntPtr
  3. */
  4. [DllImport("jnalib.dll",EntryPoint="GetVersionArray")]
  5. publicstaticexternboolGetVersionArray(IntPtrp,intnLen);
  6. //源目標(biāo)參數(shù)
  7. OSINFO[]infos=newOSINFO[2];
  8. for(inti=0;i<infos.Length;i++)
  9. {
  10. infos[i]=newOSINFO();
  11. }
  12. IntPtr[]ptArr=newIntPtr[1];
  13. ptArr[0]=Marshal.AllocHGlobal(Marshal.SizeOf(typeof(OSINFO))*2);//分配包含兩個(gè)元素的數(shù)組
  14. IntPtrpt=Marshal.AllocHGlobal(Marshal.SizeOf(typeof(OSINFO)));
  15. Marshal.Copy(ptArr,0,pt,1);//拷貝指針數(shù)組
  16. GetVersionArray(pt,2);//調(diào)用
  17. //還原成結(jié)構(gòu)體數(shù)組
  18. for(inti=0;i<2;i++)
  19. {
  20. infos[i]=(OSINFO)Marshal.PtrToStructure((IntPtr)(pt.ToInt32()+i*Marshal.SizeOf(typeof(OSINFO))),typeof(OSINFO));
  21. Console.WriteLine("OsVersion:{0}szVersion:{1}",infos[i].osVersion,infos[i].szVersion);
  22. }

三.復(fù)雜結(jié)構(gòu)體的傳遞

1. 輸出參數(shù),結(jié)構(gòu)體作為指針傳出

Cpp代碼收藏代碼
  1. typedefstruct
  2. {
  3. charname[20];
  4. intage;
  5. doublescores[30];
  6. }Student;
  7. //Class中包含結(jié)構(gòu)體數(shù)組類型
  8. typedefstruct
  9. {
  10. intnumber;
  11. Studentstudents[50];
  12. }Class;
  13. //傳入復(fù)雜結(jié)構(gòu)體測(cè)試
  14. JNAAPIintGetClass(Class*pClass,intlen);

Cpp代碼收藏代碼
  1. //接口定義
  2. [DllImport("jnalib.dll",EntryPoint="GetClass")]
  3. publicstaticexternintGetClass(IntPtrpv,intlen);
  4. //結(jié)構(gòu)體定義
  5. //Student
  6. [StructLayout(LayoutKind.Sequential)]
  7. publicstructStudent
  8. {
  9. [MarshalAs(UnmanagedType.ByValTStr,SizeConst=20)]
  10. publicstringname;
  11. publicintage;
  12. [MarshalAs(UnmanagedType.ByValArray,SizeConst=30)]
  13. publicdouble[]scores;
  14. }
  15. //Class
  16. [StructLayout(LayoutKind.Sequential)]
  17. publicstructClass
  18. {
  19. publicintnumber;
  20. [MarshalAs(UnmanagedType.ByValArray,SizeConst=50)]//指定數(shù)組尺寸
  21. publicStudent[]students;//結(jié)構(gòu)體數(shù)組定義
  22. }
  23. //調(diào)用復(fù)雜結(jié)構(gòu)體測(cè)試
  24. intsize=Marshal.SizeOf(typeof(Class))*50;
  25. IntPtrpBuff=Marshal.AllocHGlobal(size);//直接分配50個(gè)元素的空間,比Marshal.copy方便多了
  26. GetClass(pBuff,50);
  27. Class[]pClass=newClass[50];
  28. for(inti=0;i<50;i++)
  29. {
  30. IntPtrptr=newIntPtr(pBuff.ToInt64()+Marshal.SizeOf(typeof(Class))*i);
  31. pClass[i]=(Class)Marshal.PtrToStructure(ptr,typeof(Class));
  32. }
  33. Marshal.FreeHGlobal(pBuff);//釋放內(nèi)存

2. 輸入?yún)?shù), 給復(fù)雜結(jié)構(gòu)體賦值后作為輸入?yún)?shù)傳入

對(duì)于比較大的結(jié)構(gòu)體指針,無法直接應(yīng)用結(jié)構(gòu)體類型,轉(zhuǎn)化成IntPtr類型, 此時(shí)需要將原生類型轉(zhuǎn)化為指針,并給指針賦值

調(diào)用方法: Marshal.StructureToPtr(stu, ptr1, true)


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 平塘县| 江阴市| 平乐县| 翼城县| 新竹县| 泸州市| 辰溪县| 鄂伦春自治旗| 洱源县| 佛山市| 汉中市| 扶风县| 夏津县| 嫩江县| 洮南市| 新龙县| 齐河县| 塔城市| 博爱县| 郧西县| 河北省| 保康县| 达州市| 巨野县| 邻水| 平顺县| 虎林市| 昭觉县| 丹凤县| 古蔺县| 建阳市| 大埔区| 金堂县| 灌南县| 伊吾县| 方正县| 封开县| 绿春县| 贡嘎县| 昌吉市| 昂仁县|