前言
这个笔记来源于我在工作上负责开发的一个UE插件,插件里封装了Windows、Android、iOS三个平台的SDK,插件层提供统一的C++接口给项目方实现跨平台快速接入。这篇就将我的Windows原生SDK接入过程记录下来。
Ardroid平台SDK接入笔记见:
UE开发笔记:UPL在安卓中的应用实操记录_ue upl-优快云博客
iOS平台SDK接入笔记见:
UE开发笔记:UE插件接入第三方iOS原生SDK_ue与ios互相调用-优快云博客
引入SDK库
将SDK相关文件放入插件中
以下是我的插件目录结构
在build.cs中编写引入代码
引入.h头文件
//ModuleDirectory关键字是指build.cs文件所在目录。
string Root = Path.Combine(ModuleDirectory, "ThirdParty/Windows/Domestic");
PrivateIncludePaths.Add(Path.Combine(Root, "include"));
引入lib文件
PublicAdditionalLibraries.Add(Path.Combine(Root, "lib", "NDWebClientSdk.lib"));
把插件下的目录以源文件方式打包:
RuntimeDependencies.Add(file);
封装SDK API
加载dll
//插件.cpp
void* UWindowsUnionGameSDK_API::NDSDKHandle = nullptr;
FString BaseDir = FPaths::ConvertRelativePathToFull(IPluginManager::Get().FindPlugin("UEUnionGameSDK")->GetBaseDir());
FString BinPath = FPaths::Combine(*BaseDir, TEXT("Source/UEUnionGameSDK/ThirdParty/Windows/Domestic/bin"));
FPlatformProcess::PushDllDirectory(*BinPath);
NDSDKHandle = FPlatformProcess::GetDllHandle(TEXT("NDWebClientSdk.dll"));
调用dll里的API
//插件.h
typedef void(*NdLoginDialogFunc)();
//插件.cpp
NdLoginDialogFunc NdLoginDialogPtr = (NdLoginDialogFunc)FPlatformProcess::GetDllExport(NDSDKHandle, TEXT("NdLoginDialog"));
if (NdLoginDialogPtr)
{
NdLoginDialogPtr();
}
绑定dll里的回调
//SDK.h 回调定义
typedef void(*LoginSuccessEventHandler)(WebClientLoginResult& result);
/*!
登录成功回调
*/
NDWEBCLIENTSDK_API void BindLoginSuccessEvent(LoginSuccessEventHandler pHandler);
//插件.h
typedef void(*BindLoginSuccessEventFunc)(LoginSuccessEventHandler);
//插件.cpp
//获取函数指针
BindLoginSuccessEventFunc BindLoginSuccessEventPtr = (BindLoginSuccessEventFunc)FPlatformProcess::GetDllExport(NDSDKHandle, TEXT("BindLoginSuccessEvent"));
//将本地函数传入,绑定回调
BindLoginSuccessEventPtr(&OnLoginSuccess);
//定义回调函数
void UWindowsUnionGameSDK_API::OnInitSessionSuccess(const WebClientInitSessionResult& result)
{
FString JsonString;
CreateMsgJsonStr(UTF8_TO_TCHAR(result.Msg), JsonString);
AsyncTask(ENamedThreads::GameThread, [JsonString]() {
OnInitCallback.ExecuteIfBound(1, JsonString);
});
}
字符编码转换函数记录
std::string UWindowsUnionGameSDK_API::UnicodeToAnsi(const wchar_t* src)
{
if (!src)
return "";
int unicode_len = wcslen(src);
int charcount = ::WideCharToMultiByte(CP_ACP, 0, src, unicode_len, NULL, 0, NULL, NULL);
if (charcount == 0)
return "";
std::string mb;
mb.resize(charcount);
::WideCharToMultiByte(CP_ACP, 0, src, unicode_len, &mb[0], charcount, NULL, NULL);
return mb;
}