通过 Pinvoke 传递 C# 字符串
Posted
技术标签:
【中文标题】通过 Pinvoke 传递 C# 字符串【英文标题】:Passing a C# string through Pinvoke 【发布时间】:2015-04-03 21:06:47 【问题描述】:C#端:
[DllImport(@"FileGuidUtils.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
private static extern long getReparseType([MarshalAsAttribute(UnmanagedType.LPWStr)] string linkPath);
C/C++端:
__declspec(dllexport) ReparseType getReparseType(WCHAR *linkPath)
HANDLE hFile = CreateFile(linkPath, GENERIC_ALL, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, NULL);
if (hFile == INVALID_HANDLE_VALUE)
CloseHandle(hFile);
return NEITHER;
REPARSE_DATA_BUFFER *reparseDataBuffer = (REPARSE_DATA_BUFFER *)malloc(MAXIMUM_REPARSE_DATA_BUFFER_SIZE);
DWORD dwRetLen = 0;
BOOL bRet = DeviceIoControl(hFile, FSCTL_GET_REPARSE_POINT, NULL, 0, reparseDataBuffer, MAXIMUM_REPARSE_DATA_BUFFER_SIZE, &dwRetLen, NULL);
if (bRet == FALSE)
free(reparseDataBuffer);
CloseHandle(hFile);
return NEITHER;
ULONG reparseType = reparseDataBuffer->ReparseTag;
free(reparseDataBuffer);
CloseHandle(hFile);
if (reparseType == IO_REPARSE_TAG_SYMLINK)
return SYMLINK;
else if (reparseType == IO_REPARSE_TAG_MOUNT_POINT)
return JUNCTION;
return NEITHER;
linkPath 是如何传递的?它是作为 malloc 的字符串传递的,我需要在 C/C++ 端释放它还是 CLR 会为我处理它?如果它正在清理,我是否正确传递它?我可以将它作为没有[MarshalAsAttribute(UnmanagedType.LPWStr)]
的普通C# 字符串传递吗?谢谢!
【问题讨论】:
【参考方案1】:C# 会为你将 C# 字符串复制到非托管内存中,传递一个指向它的指针并在函数调用完成后删除字符串
【讨论】:
好的,我明白你所说的,我不需要改变什么吗?以上是关于通过 Pinvoke 传递 C# 字符串的主要内容,如果未能解决你的问题,请参考以下文章
使用协议缓冲区/Protobuf 的 PInvoke 通用字符串格式
C DLL 中的 PInvoke char* 在 C# 中作为字符串处理。空字符问题
如何使用 PInvoke 将 std::wstring 从 C++ 返回到 C# 而无需编写字符串缓冲区转换 [重复]