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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

Windows 平台下的C++代理类(供C # 使用)

發布時間:2025/3/15 c/c++ 15 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Windows 平台下的C++代理类(供C # 使用) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

轉自 :? http://blog.csdn.net/starlee/article/details/2864588


現在在Windows下的應用程序開發,VS.Net占據了絕大多數的份額。因此很多以前搞VC++開發的人都轉向用更強大的VS.Net。在這種情況下,有很多開發人員就面臨了如何在C#中使用C++開發好的類的問題。下面就用一個完整的實例來詳細說明怎樣用托管C++封裝一個C++類以提供給C#使用。
??? 比如,現在有一個工程名為NativeCppDll的由C++編寫的DLL,里面輸出了一個CPerson類。下面是具體的代碼:

  • //?NativeCppDll.h
  • #pragma?once
  • #ifndef?LX_DLL_CLASS_EXPORTS
  • ????#define?LX_DLL_CLASS?__declspec(dllexport)
  • #else
  • ????#define?LX_DLL_CLASS?__declspec(dllimport)
  • #endif
  • class?LX_DLL_CLASS?CPerson
  • {
  • public:
  • ????CPerson();
  • ????CPerson(const?wchar_t?*pName,?const?wchar_t?cSex,?int?iAge);
  • ????void?SetName(const?wchar_t?*pName);
  • ????wchar_t?*?GetName();
  • ????void?SetSex(const?wchar_t?cSex);
  • ????wchar_t?GetSex();
  • ????void?SetAge(int?iAge);
  • ????int?GetAge();
  • ????wchar_t?*?GetLastError();
  • private:
  • ????wchar_t?m_szName[128];
  • ????wchar_t?m_cSex;
  • ????int?m_iAge;
  • ????wchar_t?m_szLastError[128];
  • ????void?ShowError();
  • };
  • //?NativeCppDll.cpp
  • #include?"stdafx.h"
  • #include?"NativeCppDll.h"
  • #include?<iostream>
  • #include?<tchar.h>
  • using?namespace?std;
  • CPerson::CPerson()
  • {
  • ????wcscpy_s(m_szName,?_T("No?Name"));
  • ????m_cSex?=?'N';
  • ????m_iAge?=?0;
  • ????wcscpy_s(m_szLastError,?_T("No?Error"));
  • }
  • CPerson::CPerson(const?wchar_t?*pName,?const?wchar_t?cSex,?int?iAge)
  • {
  • ????wcscpy_s(m_szLastError,?_T("No?Error"));
  • ????SetName(pName);
  • ????SetSex(cSex);
  • ????SetAge(iAge);
  • }
  • void?CPerson::SetName(const?wchar_t?*pName)
  • {
  • ????if?((pName?==?NULL)?||?(wcslen(pName)?==?0)?||?(wcslen(pName)?>?127))
  • ????{
  • ????????wcscpy_s(m_szName,?_T("No?Name"));
  • ????????wcscpy_s(m_szLastError,?_T("The?length?of?the?input?name?is?out?of?range."));
  • ????????ShowError();
  • ????????return;
  • ????}
  • ????wcscpy_s(m_szName,?pName);
  • }
  • wchar_t?*?CPerson::GetName()
  • {
  • ????return?m_szName;
  • }
  • void?CPerson::SetSex(const?wchar_t?cSex)
  • {
  • ????if?((cSex?!=?'F')?&&?(cSex?!=?'M')?&&?(cSex?!=?'m')?&&?(cSex?!=?'f'))
  • ????{
  • ????????m_cSex?=?'N';
  • ????????wcscpy_s(m_szLastError,?_T("The?input?sex?is?out?of?[F/M]."));
  • ????????ShowError();
  • ????????
  • ????????return;
  • ????}
  • ????m_cSex?=?cSex;
  • }
  • wchar_t?CPerson::GetSex()
  • {
  • ????return?m_cSex;
  • }
  • void?CPerson::SetAge(int?iAge)
  • {
  • ????if?((iAge?<?0)?||?(iAge?>?150))
  • ????{
  • ????????m_iAge?=?0;
  • ????????wcscpy_s(m_szLastError,?_T("The?input?age?is?out?of?range."));
  • ????????ShowError();
  • ????????return;
  • ????}
  • ????m_iAge?=?iAge;
  • }
  • int?CPerson::GetAge()
  • {
  • ????return?m_iAge;
  • }
  • wchar_t?*?CPerson::GetLastError()
  • {
  • ????return?m_szLastError;
  • }
  • void?CPerson::ShowError()
  • {
  • ????cerr?<<?m_szLastError?<<?endl;
  • }
  • ??? 這是一個很典型的由C++開發的DLL,輸出一個完整的C++類。如果現在要求開發一個C#工程,需要用到這個DLL中輸出的C++類CPerson,該怎么辦呢?針對這個例子來說,類CPerson非常小,可以用C#重新寫一個跟這個C++類一樣的類。可是,如果需要的C++類很大,或者很多的時候,重寫工程將非常龐大。而且這樣沒有對現有的代碼進行重用,浪費了現有資源,開發起來費時費力。
    ??? 當然,還是有方法解決這個問題的。那就是用托管C++將C++類給封裝一下,然后再提供給C#來使用。下面就用代碼來詳細說明怎樣用托管C++來封裝上面的那個C++類。
    ??? 首先,要創建一個托管C++的DLL工程ManageCppDll,然后在里面添加下面的代碼:???

  • //?ManageCppDll.h
  • #pragma?once
  • #define?LX_DLL_CLASS_EXPORTS
  • #include?"../NativeCppDll/NativeCppDll.h"
  • using?namespace?System;
  • namespace?ManageCppDll?
  • {
  • ????public?ref?class?Person
  • ????{
  • ????//?包裝所有類CPerson的公有成員函數
  • ????public:
  • ????????Person();
  • ????????Person(String?^?strName,?Char?cSex,?int?iAge);
  • ????????~Person();
  • ????????property?String?^?Name
  • ????????{
  • ????????????void?set(String?^?strName);
  • ????????????String?^?get();
  • ????????}
  • ????????property?Char?Sex
  • ????????{
  • ????????????void?set(Char?cSex);
  • ????????????Char?get();
  • ????????}
  • ????????property?int?Age
  • ????????{
  • ????????????void?set(int?iAge);
  • ????????????int?get();
  • ????????}
  • ????????String?^?GetLastError();
  • ????private:
  • ????????//?類CPerson的指針,用來調用類CPerson的成員函數
  • ????????CPerson?*m_pImp;
  • ????};
  • };
  • ??? 從這個頭文件就能看出來,這是對C++類CPerson的包裝。類Person的所有公有成員函數都跟C++類CPerson一樣,只不過成員函數的參數和返回值就改成了托管C++的類型,這也是讓類Person能在C#中使用的首要條件。當然只需要對公有成員函數進行封裝,對于保護成員函數和私有成員函數則不必做任何封裝。
    ??? 類Person僅有一個私有的成員變量:一個類CPerson的指針。而類Person的所有成員函數的實現都是靠這個CPerson指針來調用類CPerson的相應成員函數來實現。
    ??? 下面是具體的實現代碼:

  • //?ManageCppDll.cpp
  • #include?"stdafx.h"
  • #include?"ManageCppDll.h"
  • #include?<vcclr.h>
  • namespace?ManageCppDll?
  • {
  • ????//?在構造函數中創建類CPerson的對象并在析構函數中將該對象銷毀
  • ????//?所有的成員函數實現都是通過指針m_pImp調用類CPerson的相應成員函數實現
  • ????Person::Person()
  • ????{
  • ????????m_pImp?=?new?CPerson();
  • ????}
  • ????Person::Person(String?^?strName,?Char?cSex,?int?iAge)
  • ????{
  • ????????//?將string轉換成C++能識別的指針
  • ????????pin_ptr<const?wchar_t>?wcName?=?PtrToStringChars(strName);
  • ????????m_pImp?=?new?CPerson(wcName,?cSex,?iAge);
  • ????}
  • ????Person::~Person()
  • ????{
  • ????????//?在析構函數中刪除CPerson對象
  • ????????delete?m_pImp;
  • ????}
  • ????void?Person::Name::set(String?^?strName)
  • ????{
  • ????????pin_ptr<const?wchar_t>?wcName?=?PtrToStringChars(strName);
  • ????????m_pImp->SetName(wcName);
  • ????}
  • ????String?^?Person::Name::get()
  • ????{
  • ????????return?gcnew?String(m_pImp->GetName());
  • ????}
  • ????void?Person::Sex::set(Char?cSex)
  • ????{
  • ????????m_pImp->SetSex(cSex);
  • ????}
  • ????Char?Person::Sex::get()
  • ????{
  • ????????return?m_pImp->GetSex();
  • ????}
  • ????void?Person::Age::set(int?iAge)
  • ????{
  • ????????m_pImp->SetAge(iAge);
  • ????}
  • ????int??Person::Age::get()
  • ????{
  • ????????return?m_pImp->GetAge();
  • ????}
  • ????String?^?Person::GetLastError()
  • ????{
  • ????????return?gcnew?String(m_pImp->GetLastError());
  • ????}
  • };
  • ??? 如果要在C#中使用類Person,首先要添加對ManageCppDll.dll的引用,然后就可以像用普通的C#類一樣的使用類Person了。比如下面這樣的代碼:

  • using?ManageCppDll;
  • Person?person?=?new?Person();
  • person.Name?=?"StarLee";
  • person.Sex?=?'M';
  • person.Age?=?28;
  • ??? 熟悉設計模式的看了上面的代碼肯定會發現,這樣的設計跟BRIDGE模式如出一轍。其實,上面的方法也算是一種BRIDGE模式,由托管C++充當了C#中使用用C++開發的類的橋梁。另外,這種形式也可以理解為ADAPTER模式,托管C++類Person就是C++類CPerson的一個適配器。通過這個橋梁,可以很容易的重用以前用C++開發的類,讓這些C++類繼續在C#中發揮它們的效用,讓開發變得事半功倍。

    總結

    以上是生活随笔為你收集整理的Windows 平台下的C++代理类(供C # 使用)的全部內容,希望文章能夠幫你解決所遇到的問題。

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