-
使用线程安全的静态缓冲区(但要注意this gotcha)。如果您不需要担心多个线程访问该函数,则删除 __declspec(thread) 说明符:
#define _WIN32_WINNT 0x0500
#define _WIN32_IE 0x0500
#define CSIDL_MYMUSIC 0x000D
#define CSIDL_MYVIDEO 0x000E
#include "dll.h"
#include <windows.h>
#include <shlobj.h>
#include <stdio.h>
__declspec(thread) char desktop_dir_buffer[((MAX_PATH*4)+1];
export LPCSTR desktop_directory()
{
wchar_t path[MAX_PATH+1] = {0};
if (SHGetFolderPathW(NULL, CSIDL_DESKTOPDIRECTORY, NULL, 0, path) != S_OK)
{
MessageBoxW(NULL, L"ERROR in SHGetFolderPathW", L"TEST", MB_OK);
return NULL;
}
MessageBoxW(NULL, path, L"TEST", MB_OK);
int buflen = WideCharToMultiByte(CP_UTF8, 0, path, lstrlenW(path), desktop_dir_buffer, MAX_PATH*4, NULL, NULL);
if (buflen <= 0)
{
MessageBoxW(NULL, L"ERROR in WideCharToMultiByte", L"TEST", MB_OK);
return NULL;
}
desktop_dir_buffer[buflen] = 0;
return desktop_dir_buffer;
}
-
让 DLL 使用自己的内存管理器动态分配缓冲区并将其返回给调用者,然后要求调用者在使用完缓冲区后将缓冲区传递回 DLL,以便可以使用 DLL 的内存管理器释放它:
#define _WIN32_WINNT 0x0500
#define _WIN32_IE 0x0500
#define CSIDL_MYMUSIC 0x000D
#define CSIDL_MYVIDEO 0x000E
#include "dll.h"
#include <windows.h>
#include <shlobj.h>
#include <stdio.h>
export LPCSTR desktop_directory()
{
wchar_t path[MAX_PATH+1] = {0};
if (SHGetFolderPathW(NULL, CSIDL_DESKTOP, NULL, 0, path) != S_OK)
{
MessageBoxW(NULL, L"ERROR in SHGetFolderPathW", L"TEST", MB_OK);
return NULL;
}
MessageBoxW(NULL, path, L"TEST", MB_OK);
int pathlen = lstrlenW(path);
int buflen = WideCharToMultiByte(CP_UTF8, 0, path, pathlen, NULL, 0, NULL, NULL);
if (buflen <= 0)
{
MessageBoxW(NULL, L"ERROR in WideCharToMultiByte", L"TEST", MB_OK);
return NULL;
}
char *buffer = new char[buflen+1];
buflen = WideCharToMultiByte(CP_UTF8, 0, path, pathlen, buffer, buflen, NULL, NULL);
if (buflen <= 0)
{
delete[] buffer;
MessageBoxW(NULL, L"ERROR in WideCharToMultiByte", L"TEST", MB_OK);
return NULL;
}
buffer[buflen] = 0;
return buffer;
}
export void free_buffer(LPVOID buffer)
{
delete[] (char*) buffer;
}
-
让 DLL 使用 Win32 API 内存管理器动态分配缓冲区并将其返回给调用者,然后调用者可以使用相同的 Win32 API 内存管理器释放它,而无需将其传递回 DLL 以释放它:
#define _WIN32_WINNT 0x0500
#define _WIN32_IE 0x0500
#define CSIDL_MYMUSIC 0x000D
#define CSIDL_MYVIDEO 0x000E
#include "dll.h"
#include <windows.h>
#include <shlobj.h>
#include <stdio.h>
export LPCSTR desktop_directory()
{
wchar_t path[MAX_PATH+1] = {0};
if (SHGetFolderPathW(NULL, CSIDL_DESKTOP, NULL, 0, path) != S_OK)
{
MessageBoxW(NULL, L"ERROR in SHGetFolderPathW", L"TEST", MB_OK);
return NULL;
}
MessageBoxW(NULL, path, L"TEST", MB_OK);
int pathlen = lstrlenW(path);
int buflen = WideCharToMultiByte(CP_UTF8, 0, path, pathlen, NULL, 0, NULL, NULL);
if (buflen <= 0)
{
MessageBoxW(NULL, L"ERROR in WideCharToMultiByte", L"TEST", MB_OK);
return NULL;
}
char *buffer = (char*) LocalAlloc(LMEM_FIXED, buflen+1);
if (!buffer)
{
MessageBoxW(NULL, L"ERROR in LocalAlloc", L"TEST", MB_OK);
return NULL;
}
buflen = WideCharToMultiByte(CP_UTF8, 0, path, pathlen, buffer, buflen, NULL, NULL);
if (buflen <= 0)
{
LocalFree(buffer);
MessageBoxW(NULL, L"ERROR in WideCharToMultiByte", L"TEST", MB_OK);
return NULL;
}
buffer[buflen] = 0;
return buffer; // caller can use LocalFree() to free it
}
-
让调用者传入它自己的缓冲区,DLL 只是填充它。这样,调用者可以决定分配和释放它的最佳方式:
#define _WIN32_WINNT 0x0500
#define _WIN32_IE 0x0500
#define CSIDL_MYMUSIC 0x000D
#define CSIDL_MYVIDEO 0x000E
#include "dll.h"
#include <windows.h>
#include <shlobj.h>
#include <stdio.h>
// the caller can set buffer=NULL and buflen=0 to calculate the needed buffer size
export int desktop_directory(LPSTR buffer, int buflen)
{
wchar_t path[MAX_PATH+1] = {0};
if (SHGetFolderPathW(NULL, CSIDL_DESKTOP, NULL, 0, path) != S_OK)
{
MessageBoxW(NULL, L"ERROR in SHGetFolderPathW", L"TEST", MB_OK);
return -1;
}
MessageBoxW(NULL, path, L"TEST", MB_OK);
int pathlen = lstrlenW(path);
int len = WideCharToMultiByte(CP_UTF8, 0, path, pathlen, buffer, buflen, NULL, NULL);
if (len <= 0)
{
MessageBoxW(NULL, L"ERROR in WideCharToMultiByte", L"TEST", MB_OK);
return -1;
}
if (!buffer)
++len;
else if (len < buflen)
buffer[len] = 0;
return len;
}