日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > C# >内容正文

C#

C#调用C++Dll封装时遇到的一系列问题

發布時間:2025/5/22 C# 47 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C#调用C++Dll封装时遇到的一系列问题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

最近幫底層開發的同時用C#重新封裝一下dll,也就是用C#類來封裝C++Dll里的方法,以供用戶使用。

之前也用到過類似的應用,大多數問題都出在類型轉換上,但是這次的應用層出不窮,所以在這里總結一下,以供自己以后查閱,也希望對大家能夠有所幫助。

  

首先,重復一下一些基本使用方法。具體的那些方式在這里就不重復講了,網上很多的。比如http://blog.csdn.net/sunboyljp/archive/2009/12/31/5110639.aspx

c++ 頭文件中的定義:

NPD_API int?? NP_Init();

C#中定義函數

[DllImport("npd_api.dll")]

public static extern int NP_Init();

?

基本類型轉換見下表(我用到過的):

BSTR——StringBuilder

LPCTSTR ——StringBuilder

LPCWSTR ——IntPtr

handle ——IntPtr

hwnd ——IntPtr

char *??——string

int * ——ref int

int & ——ref int

void * ——IntPtrs

unsigned char * ——ref byte????

BOOL ——bool

DWORD ——uint或int(我用的是uint,沒出過什么問題)

?

我的問題來了,長期的經驗教訓我知道了:

1、指針做參數時在C#中一定要使用ref 或out關鍵字,尤其是結構體指針,要不會報內存讀取錯誤,即使不報錯數據也是不太對的。呵呵

   SIPCLIENT_API void WINAPI SCCleanup(SipClient * psip);

  ?[DllImport("sipclient.dll")]
???????public static extern void SCCleanup(ref SipClient psip);

  其中SipClient是一個結構體。 

?

2、重寫結構體的時候,之前有指明類型長度或數組長度的地方,也要進行相應的標注,要不也會導致內存錯誤。?      

代碼

 typedef struct {

     char sDVRIP[16]; /* DVR IP地址 */

     char sDVRIPMask[16]; /* DVR IP地址掩碼 */

     DWORD dwNetInterface; /* 10M/100M自適應,索引 */

     WORD wDVRPort; /* 端口號 */

     BYTE byMACAddr[MACADDR_LEN]; /* 服務器的物理地址 */

 }NET_POSA_ETHERNET;

?

   public struct NET_POSA_ETHERNET
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
public string sDVRIP; //DVR IP地址
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
public string sDVRIPMask; // DVR IP地址掩碼
public uint dwNetInterface; //網絡接口 1-10MBase-T 2-10MBase-T全雙工 3-100MBase-TX 4-100M全雙工 5-10M/100M自適應
public uint wDVRPort; //端口號
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
public byte[] byMACAddr; //[MACADDR_LEN]; //PPPoE用戶名//服務器的物理地址
}

3、遇到這樣一個問題,折騰了大半天時間——http://space.cnblogs.com/q/16616/。

  最后是在C++那邊做了修改解決的,通過制定模塊定義 (.def) 文件,統一制定導出函數對應的名稱。返回值為結構體指針的函數用IntPtr也能使用了。  

代碼

SIPCLIENT_API SipClient* SCInit(const char * reaml,   const char * from_ip, int from_port,   const char * to_ip, int to_port, const char * server_id,   const char * user_id, const char * user_name, void * user_obj_param);


[DllImport("sipclient.dll")]
public static extern IntPtr SCInit(string reaml, string from_ip, int from_port,
string to_ip, int to_port, string server_id,
string user_id, string user_name, IntPtr user_obj_param);

  IntPtr client = IntPtr.Zero;
client = SIPCLIENT_API.SCInit(REALM, CLIENT_IP, CLIENT_PORT, SERVER_IP,
     SERVER_PORT, SERVER_ID, USER_ID, USER_ID, IntPtr.Zero);
if (client != IntPtr.Zero)
sipclient = (SipClient)Marshal.PtrToStructure(client, typeof(SipClient));
else
MessageBox.Show("SipClient初始化失敗!");

?

4、后來還遇到個回調函數導致的崩潰問題,又耽誤了大半天時間,下班了還耽擱了會終于找的解決發辦法了。

  剛開始同事分析出了崩潰的原因,都是回收方式惹的禍,可參見http://www.hudong.com/wiki/WINAPI,嘗試使用__stdcall,但是還是沒有解決問題

  后來實踐證明,程序是很嚴謹的,半點差錯都不能出才不會導致錯誤,思路還是__stdcall,只不過少改了東西,有兩個地方需要改,才能保證不出錯。

  參考http://hi.baidu.com/tease/blog/item/1fe7213802780f22b9998f5a.html。

  關鍵就是這兩句話

  typedef void (_stdcall *CiCiCallBack) (bool started, void* client,char *message);
  將導出函數修改為:
  extern "C" _declspec(dllexport) bool _stdcall Test(char* fileName, CiCiCallBack callback)

  一開始的時候就只修改了定義那,卻忘記了導出時的修改,差點就放棄了這條解決思路了,不過還好,所謂堅持就是勝利!

  
?5、后來封裝好拿到用戶那里用,卻總是提示說找不到C++那些dll.

  網上一查,初步定位是開發環境引起的,跟環境部署有關系。我們的開發環境是vs2008,而客戶使用的vs2010,通過幾次嘗試,問題終于了。

  首先考慮是缺少某些C++必備的運行庫,存在相互依賴關系,所以導致找不到dll。用查看Dependency Walker查看才發現真的是客戶機子上少了一些東西。

    但是此路不通,將缺少的那些東西拷貝到可執行程序目錄下,問題依舊沒有解決。但是依舊堅持這條路~

  嘗試安裝vcredist_x86.exe,以排除是否還是缺少了某些運行庫的可能,問題依然存在。

  后來我想起來之前搜索問題的時候,看到好像跟dll的Releas\Debug版本還有關系,所有又嘗試提議讓同事將他們的c++dll改為Release版的。

    因為項目是多個人一起做了,編譯Release版還花了不少時間,不過好歹問題終于解決了!

  總結:直接安裝vcredist_x86.exe,所有dll必須使用Release版的。如果使用Debug版的就必須保證可執行程序目錄下的dll是完整的,缺一不可!

  網上詳細的講解也很多,感覺這個總結的很好http://hi.baidu.com/fairysky/blog/item/e7a8366dbaa735f3431694c8.html。

?

做程序就怕出現問題,出現問題就怕不知道原因,知道原因了就好找解決的辦法啦!

總結

以上是生活随笔為你收集整理的C#调用C++Dll封装时遇到的一系列问题的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 久久精品视频9 | 好吊一区二区三区 | 中文字幕在线亚洲 | 国产麻豆电影在线观看 | 国产精品视频网 | 国产三级黄色 | 亚洲精品久久久久久久久久久久久 | 欧美一区二区三区久久综合 | 美女被男人c | 午夜免费福利网站 | 国产精品一区二区三区在线免费观看 | 高清乱码免费网 | 91国产在线看 | 欧美一卡二卡 | 一级黄色大片免费看 | 成人网免费视频 | 狠狠躁天天躁综合网 | 美女四肢被绑在床扒衣 | 日本少妇高潮抽搐 | 日韩图色 | 中文久久乱码一区二区 | 深夜福利av| 五月婷婷激情视频 | 国产女女做受ⅹxx高潮 | 五月婷婷网站 | 日韩有码中文字幕在线 | 日本一区二区不卡视频 | 国产精品女优 | 福利亚洲 | 日韩国产一级 | 午夜播放 | 欧美亚洲精品一区 | 狠狠操综合 | 一级特黄a| 国产搞逼视频 | 毛片av在线播放 | 男人天堂国产 | 97久久久| 久久黑丝 | 超碰97人| 天天宗合网| 欧美日韩人妻一区二区 | 寡妇av | 日韩一区在线播放 | 欧美老女人性生活 | 少女与动物高清版在线观看 | 国产亚洲精品aaaaaaa片 | 日韩一本在线 | 精品人妻一区二区三区在线视频 | 春色校园激情 | 日本xx片 | 亚洲一区二区不卡视频 | 亚洲区小说区图片区 | 天堂网ww | 毛片在哪里看 | 瑟瑟综合 | 一级黄网 | 国产成人无码www免费视频播放 | 国产日韩欧美综合 | 香蕉爱爱视频 | 欧美性受xxx黑人xyx性爽 | www日日日 | 日本视频精品 | 91久久精品夜夜躁日日躁欧美 | 无码人妻丰满熟妇精品区 | 在线播放不卡av | 国产黄色一区二区 | 91麻豆精品在线观看 | 欧洲免费av | 欧美日韩中文在线观看 | 国产女人高潮毛片 | 姐姐的秘密韩剧免费观看全集中文 | 国产乱子伦精品无码专区 | 国产孕妇一区二区三区 | 无码人妻精品丰满熟人区 | 日本系列第一页 | 亚洲黄网站在线观看 | 亲子乱子伦xxxx | 久久国产情侣 | 污污免费观看 | 桃花久久 | 日本国产在线播放 | 欧美日韩影院 | 久久黄色一级片 | 国产喷水福利在线视频 | 天天看黄色片 | 亚洲人成电影一区二区在线 | 国产亚洲欧美一区二区三区 | 中文字幕在线播放日韩 | 国产精品久久九九 | 日韩欧美一区二区三区四区五区 | 亚洲国产精品久 | 亚洲a人 | 一区二区日韩在线观看 | 在线一区二区观看 | 娇喘顶撞深初h1v1 | 欧美一区二区免费电影 | 久久久久国产精品区片区无码 | 日本在线视频一区二区三区 |