在c++ /CLI中将StringBuilder封送为char*(用于输入/输出)
本文关键字:用于 输出 char 输入 CLI c++ 中将 StringBuilder | 更新日期: 2023-09-27 18:03:25
我正在加载一个c++/CLI包装dll到我的c#软件中,需要一些char*参数用于底层的本地c++ dll!
我发现我需要传递一个StringBuilder来保存答案而不会得到一些访问违规?!
c#StringBuilder sB = new StringBuilder();
WrapperClass wC = new WrapperClass();
wC.Function(sB);
c++/CLI
void WrapperClass::Function(StringBuilder ^sB)
{
nativeObject->Function(charString); // need the marshaled sB
}
c++ void NativeObject::Function(char *charString)
{
// do something and save answer to charString
}
如何使用StringBuilder并将其封送为char*并返回以保存本机函数的答案?
我看到的问题有两个:第一,您正在将UNICODE对象映射到MBCS或ASCII对象,第二,StringBuilder也没有自动固定。我建议你这样做:
void WrapperClass::Function(StringBuilder^ sB)
{
// Pin a copy of the string
String^ strVal = sB->ToString();
pin_ptr<const wchar_t> psVal = PtrToStringChars(strVal);
// Translate the UNICODE string to MBCS
int wchLen = wcslen(psVal);
int pchLen = wchLen * 2 + 1;
char* pchVal = new char[pchLen];
int nclen = WideCharToMultiByte(
CP_ACP, // Source codepage (default)
WC_COMPOSITECHECK, // ch@rs with accents
strVal, // UNICODE string
wchLen, // Number of UNICODE ch@rs
pchVal, // ASCII string
pchLen, // Max number of ASCII ch@rs
0, // No default ch@rs
0 // No default flag
);
pchVal[nclen] = ''0';
// Pass the MBCS string to MBCS function
nativeObject->Function(pchVal); // need the marshaled sB
// Cleanup
delete[] pchVal;
}
您可以在以下工具的帮助下直接传入c#字符串:(简单!)
您需要利用一些互操作能力,将字符串复制到非托管堆内存中,并返回给c++本机使用。当在c++/cli层中使用时,这两个帮助程序应该可以达到目的。将字符串作为std::string&到本地c++层。本地c++完成后复制回托管内存。
//////////////////////////////////////////////////
// Marshalling Strings Functions
inline
String ^ ToManagedString(const char * pString) {
return Marshal::PtrToStringAnsi(IntPtr((char *)pString)); // Marshal pString into Managed Memory. return as a C# string reference (^).
}
inline
const std::string ToStdString(String ^ strString) {
IntPtr ptrString = IntPtr::Zero;
std::string strStdString;
try {
ptrString = Marshal::StringToHGlobalAnsi(strString); // Marshal a C# String reference into unmanaged HEAP memory space.
strStdString = (char *)ptrString.ToPointer(); // Convert C# IntPtr to char* implicitly, call assignment operator of std::string to copy.
}
finally {
if (ptrString != IntPtr::Zero) {
Marshal::FreeHGlobal(ptrString);
}
}
return strStdString; // return std::string copied out of interop unmanaged heap space
}
//////////////////////////////////////////////////////
把上面的代码放到c++/cli层的头文件中。非常方便的接口工具。祝你好运。