首頁(yè)考試吧論壇Exam8視線考試商城網(wǎng)絡(luò)課程模擬考試考友錄實(shí)用文檔求職招聘論文下載
2013中考
法律碩士
2013高考
MBA考試
2013考研
MPA考試
在職研
中科院
考研培訓(xùn) 自學(xué)考試 成人高考
四 六 級(jí)
GRE考試
攻碩英語(yǔ)
零起點(diǎn)日語(yǔ)
職稱(chēng)英語(yǔ)
口譯筆譯
申碩英語(yǔ)
零起點(diǎn)韓語(yǔ)
商務(wù)英語(yǔ)
日語(yǔ)等級(jí)
GMAT考試
公共英語(yǔ)
職稱(chēng)日語(yǔ)
新概念英語(yǔ)
專(zhuān)四專(zhuān)八
博思考試
零起點(diǎn)英語(yǔ)
托?荚
托業(yè)考試
零起點(diǎn)法語(yǔ)
雅思考試
成人英語(yǔ)三級(jí)
零起點(diǎn)德語(yǔ)
等級(jí)考試
華為認(rèn)證
水平考試
Java認(rèn)證
職稱(chēng)計(jì)算機(jī) 微軟認(rèn)證 思科認(rèn)證 Oracle認(rèn)證 Linux認(rèn)證
公 務(wù) 員
導(dǎo)游考試
物 流 師
出版資格
單 證 員
報(bào) 關(guān) 員
外 銷(xiāo) 員
價(jià)格鑒證
網(wǎng)絡(luò)編輯
駕 駛 員
報(bào)檢員
法律顧問(wèn)
管理咨詢
企業(yè)培訓(xùn)
社會(huì)工作者
銀行從業(yè)
教師資格
營(yíng)養(yǎng)師
保險(xiǎn)從業(yè)
普 通 話
證券從業(yè)
跟 單 員
秘書(shū)資格
電子商務(wù)
期貨考試
國(guó)際商務(wù)
心理咨詢
營(yíng) 銷(xiāo) 師
司法考試
國(guó)際貨運(yùn)代理人
人力資源管理師
廣告師職業(yè)水平
衛(wèi)生資格 執(zhí)業(yè)醫(yī)師 執(zhí)業(yè)藥師 執(zhí)業(yè)護(hù)士
會(huì)計(jì)從業(yè)資格
基金從業(yè)資格
統(tǒng)計(jì)從業(yè)資格
經(jīng)濟(jì)師
精算師
統(tǒng)計(jì)師
會(huì)計(jì)職稱(chēng)
法律顧問(wèn)
ACCA考試
注冊(cè)會(huì)計(jì)師
資產(chǎn)評(píng)估師
審計(jì)師考試
高級(jí)會(huì)計(jì)師
注冊(cè)稅務(wù)師
國(guó)際內(nèi)審師
理財(cái)規(guī)劃師
美國(guó)注冊(cè)會(huì)計(jì)師
一級(jí)建造師
安全工程師
設(shè)備監(jiān)理師
公路監(jiān)理師
公路造價(jià)師
二級(jí)建造師
招標(biāo)師考試
物業(yè)管理師
電氣工程師
建筑師考試
造價(jià)工程師
注冊(cè)測(cè)繪師
質(zhì)量工程師
巖土工程師
造價(jià)員考試
注冊(cè)計(jì)量師
環(huán)保工程師
化工工程師
咨詢工程師
結(jié)構(gòu)工程師
城市規(guī)劃師
材料員考試
監(jiān)理工程師
房地產(chǎn)估價(jià)
土地估價(jià)師
安全評(píng)價(jià)師
房地產(chǎn)經(jīng)紀(jì)人
投資項(xiàng)目管理師
環(huán)境影響評(píng)價(jià)師
土地登記代理人
繽紛校園 實(shí)用文檔 英語(yǔ)學(xué)習(xí) 作文大全 求職招聘 論文下載 訪談|游戲
軟件水平考試
軟件水平考試資訊
軟件水平考試試題
軟件水平考試專(zhuān)項(xiàng)輔導(dǎo)
軟件水平考試交流互動(dòng)
軟件水平考試交流互動(dòng)
您現(xiàn)在的位置: 考試吧 > 軟件水平考試 > 復(fù)習(xí)資料 > 程序員資料 > 正文

2012年軟考程序員輔導(dǎo):C語(yǔ)言封送結(jié)構(gòu)體數(shù)組

  在使用第三方的非托管API時(shí),我們經(jīng)常會(huì)遇到參數(shù)為指針或指針的指針這種情況,

  一般我們會(huì)用IntPtr指向我們需要傳遞的參數(shù)地址;

  但是當(dāng)遇到這種一個(gè)導(dǎo)出函數(shù)時(shí),我們?nèi)绾握_的使用IntPtr呢,

  extern “C” __declspec(dllexport) int GetClass(Class pClass[50]) ;

  由于這種情況也經(jīng)常可能遇到,所以我制作了2個(gè)示例程序來(lái)演示下如何處理這種非托管函數(shù)的調(diào)用!

  首先創(chuàng)建一個(gè)C++ 的DLL 設(shè)置一個(gè)如上的導(dǎo)出函數(shù)

  #include #include typedef struct Student { char name[20];int age;double scores[32];}Student;typedef struct Class { int number;Student students[126];}Class;extern “C” __declspec(dllexport) int GetClass(Class pClass[50])

  { for(int i=0;i<50;i++)

  { pClass[i].number=i;for(int j=0;j<126;j++)

  { memset(pClass[i].students[j].name,0,20);sprintf(pClass[i].students[j].name,“name_%d_%d”,i,j);pClass[i].students[j].age=j%2==0?15:20;} return 0;}上面DLL 的導(dǎo)出函數(shù)要求傳遞的參數(shù)為它自定義的Class結(jié)構(gòu)體數(shù)組, 那么我們?cè)贑#調(diào)用它時(shí)也要自定義對(duì)應(yīng)的結(jié)構(gòu)體了,

  我們可以定義為如下:

  [StructLayout(LayoutKind.Sequential)] struct Student { [MarshalAs(UnmanagedType.ByValTStr,SizeConst=20)] public string name;public int age;[MarshalAs(UnmanagedType.ByValArray,SizeConst=32)] public double[] scores;} [StructLayout(LayoutKind.Sequential)] struct Class { public int number;[MarshalAs(UnmanagedType.ByValArray,SizeConst=126)] public Student[] students;}需要注意的是,這2個(gè)結(jié)構(gòu)體中的數(shù)組大小一定要跟C++中的限定一樣大小哦,接下來(lái)如何使用這個(gè)API來(lái)正確的獲取數(shù)據(jù)呢,大多數(shù)人可能想到像這樣的處理方式

  Class myclass = new Class();IntPtr ptr=Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Class)));GetClass(ptr);Marshal.FreeHGlobal(ptr);沒(méi)錯(cuò),這樣的處理是沒(méi)問(wèn)題的,但是我們的API的參數(shù)是Class數(shù)組,這種處理方式只是傳遞一個(gè)Class結(jié)構(gòu)體參數(shù),所以這種方式在這里就不太合適了,!

  那大家就想到先Class[] myclass = new Class[MaxClass]; 然后在用Marshal.AllocHGlobal 來(lái)獲取myclass 數(shù)據(jù)的指針,

  其實(shí)這樣也是錯(cuò)的, 因?yàn)?Class結(jié)構(gòu)中包含了,不能直接封送的Student結(jié)構(gòu),所以無(wú)論如何上面的想法是錯(cuò)誤的!

  那要怎么辦呢,其實(shí)很簡(jiǎn)單,就是先分配一段非托管內(nèi)存,并調(diào)用API后,再將非托管內(nèi)容數(shù)據(jù)讀取到托管結(jié)構(gòu)體數(shù)據(jù)中!

  示例C語(yǔ)言封送結(jié)構(gòu)體數(shù)組演示代碼如下

  1 static void Main(string[] args)

  2 {

  3 int size = Marshal.SizeOf(typeof(Class)) * 50;

  4 byte[] bytes = new byte[size];

  5 IntPtr pBuff = Marshal.AllocHGlobal(size);

  6 Class[] pClass = new Class[50];

  7 GetClass(pBuff);

  8 for (int i = 0; i < 50; i++)

  9 {

  10 IntPtr pPonitor = new IntPtr(pBuff.ToInt64() + Marshal.SizeOf(typeof(Class)) * i);

  11 pClass[i] = (Class)Marshal.PtrToStructure(pPonitor, typeof(Class));

  12 }

  13 Marshal.FreeHGlobal(pBuff);

  14 Console.ReadLine();

  15 }有興趣的不妨自己測(cè)試一下C語(yǔ)言封送結(jié)構(gòu)體數(shù)組,看看輸出結(jié)果是否正確

文章搜索
軟件水平考試欄目導(dǎo)航
版權(quán)聲明:如果軟件水平考試網(wǎng)所轉(zhuǎn)載內(nèi)容不慎侵犯了您的權(quán)益,請(qǐng)與我們聯(lián)系800@exam8.com,我們將會(huì)及時(shí)處理。如轉(zhuǎn)載本軟件水平考試網(wǎng)內(nèi)容,請(qǐng)注明出處。