C#获得C++字符串

来源:互联网 发布:武汉专业淘宝摄影 编辑:程序博客网 时间:2024/06/04 12:34

这阵在做C++动态库与C#相互调用的工作,遇到C#获得C++字符串的问题,解决问题时发现也有不少人在问。

自己已经完成了这一部分功能的封装,把代码贴出来供大家分享。


环境:PC VS2008

C#定义委托GetCStringFunction,用于传递希望在C++调用的返回wstring的函数。GetCString调用委托,并把返回的指向wstring的指针转为C# string输出,然后删除掉C++中创建的存储wstring的内存。


C#通过委托在C++中调用的函数在获得C++ wstring后调用CString2CSharpIntPtr创建内存,把wstring存储在此处,并把指针返回给C#。然后等待c#调用DeleteStrMemory释放该内存。


其中的DDInterfaceX pDDInterfaceX是传递的一个C++中类使用的指针,用于C++中调用类成员函数获得wstring。这部分与本题目无关,可略过。




C#代码:

using System.Runtime.InteropServices;//使用DllImport导入C++ Dll需要此命名空间GeneralMarco.DDImport== @"..\..\..\debug\CommTest.dll";//存储C++ Dll位置//功能:用于获得C++环境下的pItemRef(优先)和pItem指向的String数据//输入:DDInterfaceX pDDInterfaceX的pItemRef(优先)和pItem//输出:用于转换成字符串的指针DestinationStrPtr//返回值:0 成功,1 失败,2 VIRTUALCALLERRpublic delegate int GetCStringFunction(ref DDInterfaceX pDDInterfaceX, ref IntPtr DestinationStrPtr); [DllImport(GeneralMarco.DDImport)] //功能:在C++中释放获得C++字符串时分配的内存 //输入:StringPtr //输出:无 //返回值:返回true为成功 public static extern bool DeleteStrMemory(IntPtr StringPtr); //功能:C#程序封装,用于获得C++运行环境下的String数据。//输入:DDInterfaceX pDDInterfaceX的pItemRef(优先)和pItem,SourceFunction为调用的C++方法 //输出:DestinationString,获得string //返回值:0 成功,非0 失败 //Example://DDInterface.GetCStringFunction GetStringFunc; //GetStringFunc = DDInterface.GetLabel; //string str; //DDInterface.GetCString(out str, ref myDDInterface.pDDInterfaceX, GetStringFunc); public static int GetCString(out string DestinationString, ref DDInterfaceX pDDInterfaceX, GetCStringFunction SourceFunction) { int returnCode=0; IntPtr DestinationStrPtr = new IntPtr(); returnCode = SourceFunction(ref pDDInterfaceX, ref DestinationStrPtr);//获得字符串指针指向相应的C++字符串; DestinationString = System.Runtime.InteropServices.Marshal.PtrToStringAuto(DestinationStrPtr);//将字符串指针转为字符串;DDInterface.DeleteStrMemory(DestinationStrPtr);//释放C++内存; return returnCode; }[DllImport(GeneralMarco.DDImport)]        //功能:获得DD item项的Label,返回到DestinationStrPtr        //输入:DDInterfaceX 结构体引用        //输出:DestinationStrPtr 指针        //返回值:0 成功,非0 失败        public static extern int GetLabel(ref DDInterfaceX pDDInterfaceX,ref IntPtr DestinationStrPtr);


C++代码

#define DDExport extern "C" __declspec(dllexport)DDExport int GetLabel(DDInterfaceX* pDDInterface,wchar_t** DestinationStr){//将pDDinterface->m_pItem或pDDInterface->m_pItemRef中的标签返回到C# string 指针DestinationStr。//返回值0成功,其他失败 wstring szLabel, dummyHelp;// try wide 28jan08bool    stringFull = false;RETURNCODE rc=0;if (pDDInterface->m_pItemRef)//如果有关联项,需要通过关联项获得label?    {        rc=rc||pDDInterface->m_pItemRef->getItemLabel(szLabel, stringFull,dummyHelp); // could be different from item label     }if ( szLabel.empty() && GetItem(pDDInterface) )//自己得到label{rc=rc||pDDInterface->m_pItem->Label(szLabel);}rc=rc||CString2CSharpIntPtr(szLabel.c_str(),DestinationStr);return rc;}int CString2CSharpIntPtr( CString SourceStr,wchar_t** DestinationStr){//将C++Cstring SourceStr数据转为C# String,以ref intptr形式传回,返回值0成功,其他失败。RETURNCODE rc=0;int len = sizeof(wchar_t) * (SourceStr.GetLength() + 1) ;*DestinationStr = new wchar_t[len];memset(*DestinationStr, 0, len);rc=wcscpy_s(*DestinationStr, len, CT2CW(SourceStr));return rc;}DDExport bool DeleteStrMemory(void *CSharpIntPtr){//释放CString2CSharpIntPtr中的内存空间if (CSharpIntPtr != NULL){delete CSharpIntPtr;CSharpIntPtr = NULL;}return true;}



 
原创粉丝点击