程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> C#調用C和C++函數的一點區別

C#調用C和C++函數的一點區別

編輯:C#入門知識

最近做U800電話的二次開發,需要調用廠商的C函數庫來打電話,後來想加入通話錄音功能,但發現程序默認生產的WAV文件過大,又找了個WAV轉MP3的C++函數庫程序,出了點問題。下面是轉MP3的程序接口(頭文件):

 _MP3ENC_H_

 mp3_enc( * inWavName, nRate, *

按照C#調用非托管程序的約定,聲明一個對應的C#函數接口:

 [DllImport(, CharSet =    mp3_enc( inWavName,  nRate,  outMP3Name);

然後這樣調用改函數:

 mp3_enc(txtWavFile.Text, , );

結果出現這樣的異常信息:

 對 PInvoke 函數“U800Test!U800Test.Form1::mp3_enc”的調用導致堆棧不對稱。原因可能是托管的 PInvoke 簽名與非托管的目標簽名不匹配。請檢查 PInvoke 簽名的調用約定和參數與非托管的目標簽名是否匹配。

跟原來調用C函數庫的方法仔細對比,發現沒有區別,而C函數代碼卻可以正常使用:
打電話的C函數接口:

USBDLL_API  _stdcall StartDial( iDevIdx, * szDest);    

對應的C#函數接口:

  [DllImport(, CharSet =    StartDial( iDevIdx, szDest);


再看看C++的調用函數的錯誤信息,難道是C++字符串類型不一致?需要C++使用Unicode 字符?於是將C#的函數接口改成:

 [DllImport(, CharSet =    mp3_enc( inWavName,  nRate,  outMP3Name);

結果C#程序直接崩潰,連Try....Catch.... 都沒用。

最後,在網上搜索了半天,發現有這個說法:

DllImport還有一個CallingConvention的屬性,默認值是CallingCovention.Stdcall,  此處更改成Cdecl(c/c++默認調用方式)就可以了。VS2010下必須得指定這個屬性才能運行, 同樣的代碼在VS2008下卻不存在這樣的問題, 奇怪 ...

正確的C++ 函數C#調用接口應該是這樣:

[DllImport(, CharSet = CharSet.Ansi, CallingConvention =    mp3_enc( inWavName,  nRate,  outMP3Name);

 

 

 

 

 

 

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved