如何将const wchar_t *从C DLL自动转换为C#字符串

问题描述 投票:3回答:2

这只是好奇心。也许这个世界上有人做过这样的事情:

我必须导出C函数并通过DllImport从C#代码加载它

const wchar_t * SysGetLibInfo() {
    return dllmanager.SysGetLibInfo();
}

最好这样做是最好的做法,是声明IntPtr,然后使用某些函数将其转换为字符串。换句话说,类似这样的东西

[DllImport(dll, CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr SysGetLibInfo(); 
// ...
Marshal.PtrToStringUni(SysGetLibInfo());

此方法有效。但是有没有办法自动做到这一点?使SysGetLibInfo返回一个字符串?我发现了这样的建议:

[DllImport(dll, CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.LPWStr)]
private static extern string SysGetLibInfo();

但是它不起作用,并且根据各种示例和少量报告,它不起作用。

是否有一种方法可以编写自己的属性(如MarshalAs),该属性会将IntPtr转换为字符串?类似于以下内容:

[DllImport(dll, CallingConvention = CallingConvention.Cdecl)]
[return: MyOwnMarshalPtrToStringUni]
private static extern string SysGetLibInfo();

预先感谢您提供任何信息或有用的链接,示例,书籍。同样,这只是好奇。

P.S。建议不要使用SysGetLibInfo包装一个单独的函数,该函数使用PtrToStringUni将结果转换为字符串;)

c# c++ dll wchar-t interopservices
2个回答
1
投票
http://msdn.microsoft.com/en-us/library/w22x2hw6.aspx

[DllImport(dll, CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(MyMarshaller))] private static extern string SysGetLibInfo();


1
投票

除非将LPWStr值与非托管字符串一起使用,否则

这很好。本机代码:

// header extern "C" __declspec(dllexport) wchar_t* SysGetLibInfo(void); // implementation extern "C" __declspec(dllexport) wchar_t* SysGetLibInfo(void) { return TEXT("Hello from unmanaged world!"); }

托管代码:

[DllImport("NativeLibrary.dll", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.LPTStr)] static extern string SysGetLibInfo();

如果您将以这种方式更改本机功能:

extern "C" __declspec(dllexport) wchar_t* SysGetLibInfo(void) { wchar_t* pStr = (wchar_t*)CoTaskMemAlloc(100); ZeroMemory(pStr, 100); wcscpy(pStr, TEXT("Hello from unmanaged world!")); return pStr; }

然后[return: MarshalAs(UnmanagedType.LPWStr)]也将起作用。
© www.soinside.com 2019 - 2024. All rights reserved.