字符集WideCharToMultiByte
GDAL C#封装对中文字符转换过程中存在问题。
C++封装一个Win32 DLL,采用Unicode字符集。使用标准头文件。
https://msdn.microsoft.com/en-us/library/dd319072(VS.85).aspx

1 class CodePageHelper
2 {
3 public:
4 CodePageHelper(void);
5 ~CodePageHelper(void);
6 static wchar_t* ANSIToUnicode( const char* str );
7 static char* UnicodeToANSI( const wchar_t* str );
8 static wchar_t* UTF8ToUnicode( const char* str );
9 static char* UnicodeToUTF8( const wchar_t* str );
10 };

1 #include "StdAfx.h"
2 #include "CodePageHelper.h"
3
4
5 CodePageHelper::CodePageHelper(void)
6 {
7 }
8
9
10 CodePageHelper::~CodePageHelper(void)
11 {
12 }
13
14 // ANSI to Unicode
15 wchar_t* CodePageHelper:: ANSIToUnicode( const char* str )
16 {
17 int unicodeLen = ::MultiByteToWideChar( CP_ACP,
18 0,
19 str,
20 -1,
21 NULL,
22 0 );
23 wchar_t * pUnicode;
24 pUnicode = new wchar_t[unicodeLen+1];
25 memset(pUnicode,0,(unicodeLen+1)*sizeof(wchar_t));
26 ::MultiByteToWideChar( CP_ACP,
27 0,
28 str,
29 -1,
30 (LPWSTR)pUnicode,
31 unicodeLen );
32 wchar_t* rt;
33 rt = ( wchar_t* )pUnicode;
34 //delete pUnicode;
35
36 return rt;
37 }
38 // Unicode to ANSI
39 char* CodePageHelper:: UnicodeToANSI( const wchar_t* str )
40 {
41 char* pElementText;
42 int iTextLen;
43 // wide char to multi char
44 iTextLen = WideCharToMultiByte( CP_ACP,
45 0,
46 str,
47 -1,
48 NULL,
49 0,
50 NULL,
51 NULL );
52 pElementText = new char[iTextLen + 1];
53 memset( ( void* )pElementText, 0, sizeof( char ) * ( iTextLen + 1 ) );
54 ::WideCharToMultiByte( CP_ACP,
55 0,
56 str,
57 -1,
58 pElementText,
59 iTextLen,
60 NULL,
61 NULL );
62 char* strText;
63 strText = pElementText;
64 //delete[] pElementText;
65 return strText;
66 }
67 // UTF-8 to Unicode
68 wchar_t* CodePageHelper::UTF8ToUnicode( const char* str )
69 {
70 int unicodeLen = ::MultiByteToWideChar( CP_UTF8,
71 0,
72 str,
73 -1,
74 NULL,
75 0 );
76 wchar_t * pUnicode;
77 pUnicode = new wchar_t[unicodeLen+1];
78 memset(pUnicode,0,(unicodeLen+1)*sizeof(wchar_t));
79 ::MultiByteToWideChar( CP_UTF8,
80 0,
81 str,
82 -1,
83 (LPWSTR)pUnicode,
84 unicodeLen );
85 wchar_t* rt;
86 rt = ( wchar_t* )pUnicode;
87 //delete pUnicode;
88
89 return rt;
90 }
91 // Unicode to UTF-8
92
93 char* CodePageHelper::UnicodeToUTF8( const wchar_t* str )
94 {
95 char* pElementText;
96 int iTextLen;
97 // wide char to multi char
98 iTextLen = WideCharToMultiByte( CP_UTF8,
99 0,
100 str,
101 -1,
102 NULL,
103 0,
104 NULL,
105 NULL );
106 pElementText = new char[iTextLen + 1];
107 memset( ( void* )pElementText, 0, sizeof( char ) * ( iTextLen + 1 ) );
108 ::WideCharToMultiByte( CP_UTF8,
109 0,
110 str,
111 -1,
112 pElementText,
113 iTextLen,
114 NULL,
115 NULL );
116 char* strText;
117 strText = pElementText;
118 //delete[] pElementText;
119 return strText;
120 }

1 #ifdef DEMIMP_EXPORTS 2 #define CPL_DLL __declspec(dllexport) 3 #else 4 #define CPL_DLL __declspec(dllimport) 5 #endif 6 7 #ifndef CPL_DISABLE_STDCALL 8 # define CPL_STDCALL __stdcall 9 #endif 10 11 extern "C" 12 { 13 HANDLE CPL_DLL WINAPI GetMetaData(LPWSTR filepath); 14 };
1 HANDLE CPL_DLL WINAPI GetMetaData(LPWSTR filepath)
2 {
3 //char* file=CodePageHelper::UnicodeToUTF8((const wchar_t*)filepath);
4
5 char* file1=CodePageHelper::UnicodeToANSI((const wchar_t*)filepath);
6 //const wchar_t* file2=filepath;
7 GDALAllRegister();
8 CPLSetConfigOption("GDAL_FILENAME_IS_UTF8","NO");
9 GDALDataset *pDSrc = (GDALDataset *)GDALOpen(file1, GA_ReadOnly);
10 if (pDSrc == NULL)
11 {
12 return 0;
13 }
14 char** metadata=pDSrc->GetMetadata("");
15 return metadata;
16 }
C# P/Invoke调用:
1 [DllImport("GDALRaster.dll", EntryPoint = "GetMetaData", CharSet = CharSet.Unicode)]
2 private static extern IntPtr CSharp_GetMetadata([In, MarshalAs(UnmanagedType.LPWStr)]string filepath);
解析字符串:
1 public static string[] GetMetaData(string filePath)
2 {
3 IntPtr cPtr = CSharp_GetMetadata(filePath);
4 if (cPtr == IntPtr.Zero) throw new Exception("打开失败");
5
6 IntPtr objPtr;
7 int count = 0;
8 if (cPtr != IntPtr.Zero)
9 {
10 while (Marshal.ReadIntPtr(cPtr, count * IntPtr.Size) != IntPtr.Zero)
11 ++count;
12 }
13 string[] ret = new string[count];
14 if (count > 0)
15 {
16 for (int cx = 0; cx < count; cx++)
17 {
18 objPtr = System.Runtime.InteropServices.Marshal.ReadIntPtr(cPtr, cx * System.Runtime.InteropServices.Marshal.SizeOf(typeof(IntPtr)));
19 ret[cx] = (objPtr == IntPtr.Zero) ? null : System.Runtime.InteropServices.Marshal.PtrToStringAnsi(objPtr);
20 }
21 }
22 return ret;
23 //double[] temp = new double[xsize * ysize];
24 //Marshal.Copy(pData, temp, 0, xsize * ysize);
25 //FreeData(pData);
26 //return temp;
27
28 }
作者:太一吾鱼水
文章未经说明均属原创,学习笔记可能有大段的引用,一般会注明参考文献。
欢迎大家留言交流,转载请注明出处。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· Vue3状态管理终极指南:Pinia保姆级教程
2013-04-24 [WorldWind学习]13.日志类Log