轉自:http://www.cppblog.com/mzty/archive/2007/05/29/25062.html
C++與.NET中基礎類型的對應及轉化
前言:爲了介紹C#寫界面,C++寫算法的快捷交互開發方式,首先介紹c++,C#內部的DLL,COM調用.
一,基礎類型
二,字符類型
Author - Nishant Sivakumar
Copyright(C) - Nishant Sivakumar 2005
***/
#pragma once
#include <wtypes.h>
#include <vector>
#include <string>
#include <vcclr.h>
using namespace System;
using namespace System::Runtime::InteropServices;
namespace StringUtilities
{
//Class StringConvertorBase
//Serves as the abstract base class for StringConvertor and implements
//default initialization and clean-up code.
ref class StringConvertorBase abstract
{
protected:
StringConvertorBase()
{
InternalInit();
}
~StringConvertorBase()
{
InternalCleanUp();
}
//While the finalizer is included to take care of cases
//where the destructor does not get called, it's highly inefficient
//and ruins the purpose of the class if the class is not used
//with deterministic destruction. It's recommended that you either use
//the auto-variable non-handle declaration format or explicitly
//call delete on the StringConvertor object after use.
!StringConvertorBase()
{
InternalCleanUp();
#ifdef _DEBUG
throw gcnew Exception("Finalizer should not have got called");
#else
Diagnostics::Trace::WriteLine("Finalizer should not have got called");
#endif
}
std::vector< gcroot<IntPtr> >* m_vec_hglobal;
std::vector< gcroot<IntPtr> >* m_vec_bstr;
//Frees the allocated unmanaged memory
void InternalCleanUp()
{
for each(gcroot<IntPtr> ptr in *m_vec_hglobal)
{
Marshal::FreeHGlobal(ptr);
}
m_vec_hglobal->clear();
delete m_vec_hglobal;
for each(gcroot<IntPtr> ptr in *m_vec_bstr)
{
Marshal::FreeBSTR(ptr);
}
m_vec_bstr->clear();
delete m_vec_bstr;
}
void InternalInit()
{
m_vec_hglobal = new std::vector< gcroot<IntPtr> >();
m_vec_bstr = new std::vector< gcroot<IntPtr> >();
}
};
//Class StringConvertor
//General purpose convertor class for System::String (both from and to)
ref class StringConvertor : StringConvertorBase
{
protected:
String^ m_String; //The internal System::String object
public:
//Various constructors each taking a different type as argument
StringConvertor(String^ s) : m_String(s)
{
if(m_String == nullptr)
throw gcnew Exception("You need to pass a non-null String");
}
StringConvertor(const char* s)
{
if(s == nullptr)
throw gcnew Exception("You need to pass a non-null char*");
m_String = gcnew String(s);
}
StringConvertor(const __wchar_t* s)
{
if(s == nullptr)
throw gcnew Exception("You need to pass a non-null __wchar_t*");
m_String = gcnew String(s);
}
StringConvertor(array<Char>^ s)
{
if(s == nullptr)
throw gcnew Exception("You need to pass a non-null Char array");
m_String = gcnew String(s);
}
StringConvertor(BSTR s)
{
if(s == nullptr)
throw gcnew Exception("You need to pass a non-null BSTR");
m_String = gcnew String(s);
}
StringConvertor(std::string s)
{
m_String = gcnew String(s.c_str());
}
StringConvertor(std::wstring s)
{
m_String = gcnew String(s.c_str());
}
//Methods
virtual String^ ToString() override
{
return m_String;
}
//Operators
operator String^()
{
return m_String;
}
//Properties
//Returns an interior pointer to the underlying string. The
//pointer is of type const Char so you can only read through it.
property interior_ptr<const Char> InteriorConstCharPtr
{
interior_ptr<const Char> get()
{
return PtrToStringChars(m_String);
}
}
//Returns an interior pointer to the underlying string that can be
//written to. Use with extreme care, as you are directly editing the
//System::String's internal character buffer.
property interior_ptr<Char> InteriorCharPtr
{
interior_ptr<Char> get()
{
return const_cast< interior_ptr<Char> >(InteriorConstCharPtr);
}
}
//Generic character mapping to use with LPTSTR.
//Since it's a #define, intellisense won't show it.
#ifdef _UNICODE
#define NativeTCharPtr NativeWideCharPtr
#else
#define NativeTCharPtr NativeCharPtr
#endif
//Returns a char* (allocated on the native heap)
property char* NativeCharPtr
{
char* get()
{
IntPtr ptr = Marshal::StringToHGlobalAnsi(m_String);
if(ptr != IntPtr::Zero)
{
m_vec_hglobal->push_back(ptr);
return reinterpret_cast<char*>(static_cast<void*>(ptr));
}
else
return nullptr;
}
}
//Returns a __wchar_t* (allocated on the native heap)
property __wchar_t* NativeWideCharPtr
{
__wchar_t* get()
{
IntPtr ptr = Marshal::StringToHGlobalUni(m_String);
if(ptr != IntPtr::Zero)
{
m_vec_hglobal->push_back(ptr);
return reinterpret_cast<__wchar_t*>(static_cast<void*>(ptr));
}
else
return nullptr;
}
}
//Returns a CLI array of Chars
property array<Char>^ CharArray
{
array<Char>^ get()
{
return m_String->ToCharArray();
}
}
//Returns a BSTR allocated natively (unmanaged heap)
property BSTR BSTRCopy
{
BSTR get()
{
IntPtr ptr = Marshal::StringToBSTR(m_String);
if(ptr != IntPtr::Zero)
{
m_vec_bstr->push_back(ptr);
return reinterpret_cast<BSTR>(static_cast<void*>(ptr));
}
else
return nullptr;
}
}
//Returns an std::string object
property std::string STLAnsiString
{
std::string get()
{
IntPtr ptr = Marshal::StringToHGlobalAnsi(m_String);
if(ptr != IntPtr::Zero)
{
std::string tmp(reinterpret_cast<char*>(static_cast<void*>(ptr)));
Marshal::FreeHGlobal(ptr);
return tmp;
}
return std::string();
}
}
//Returns an std::wstring object
property std::wstring STLWideString
{
std::wstring get()
{
IntPtr ptr = Marshal::StringToHGlobalUni(m_String);
if(ptr != IntPtr::Zero)
{
std::wstring tmp(reinterpret_cast<__wchar_t*>(static_cast<void*>(ptr)));
Marshal::FreeHGlobal(ptr);
return tmp;
}
return std::wstring();
}
}
};
}
三,其他
對於COM,在託管代碼和非託管代碼之間進行的所有調用都必須滿足各自編程模型強加的要求。託管和非託管編程模型在很多方面是不同的。下表顯示了每個模型的定義特徵。
特徵 | 非託管模型 | 託管模型 |
---|---|---|
基於接口 |
基於對象 |
|
GUID |
強名稱 |
|
HRESULT |
異常 |
|
二進制標準 |
類型標準 |
|
類型庫 |
元數據 |
|
非類型安全 |
可選安全 |
|
不可變的 |
靈活的 |
COM類型對應:
COM 值類型 | COM 引用類型 | 系統類型 |
---|---|---|
bool |
bool * |
|
char、small |
char *、small * |
|
short |
short * |
|
long、int |
long *、int * |
|
Hyper |
hyper * |
|
unsigned char、byte |
unsigned char *、byte * |
|
wchar_t、unsigned short |
wchar_t *、unsigned short * |
|
unsigned long、unsigned int |
unsigned long *、unsigned int * |
|
unsigned hyper |
unsigned hyper * |
|
float |
float * |
|
double |
double * |
|
VARIANT_BOOL |
VARIANT_BOOL * |
|
void* |
void ** |
|
HRESULT |
HRESULT * |
System.Int16 或System.IntPtr |
SCODE |
SCODE * |
System.Int32 |
BSTR |
BSTR * |
|
LPSTR 或 [string, ...] char * |
LPSTR * |
System.String |
LPWSTR 或 [string, …] wchar_t * |
LPWSTR * |
System.String |
VARIANT |
VARIANT * |
|
DECIMAL |
DECIMAL * |
|
DATE |
DATE * |
|
GUID |
GUID * |
|
CURRENCY |
CURRENCY * |
|
IUnknown * |
IUnknown ** |
System.Object |
IDispatch * |
IDispatch ** |
System.Object |
SAFEARRAY( type ) |
SAFEARRAY( type ) * |
type [] |
四,參考:
http://www.codeproject.com/managedcpp/StringConvertor.asp
http://www.voidnish.com/articles/ShowArticle.aspx?code=StringConvertor