UE4 C++调用C# DLL(DllExport方法)
之前看见园子里一篇C++调用C#的文章,参考后拿UE试一下。刚开始尝试了C# dll > CLR C++ DLL > Native C++ DLL的做法,
原生环境下是可以的,但是到UE4里会Crash。
后来换成了Dll Export(UnmanagedExports)的做法,并测试成功。
当然对比UnrealCLR之类的方案,这个只能解一时之需。
1.注意事项
使用Nuget上的UnmanagedExports1.2.7版本,各种坑点和问题总结如下:
- .NetFramwork dll从4.5-4.8应该都是可以导出的,.Net standard(core)的dll导出测试失败。
- 必须指定导出平台是x86还是x64,不要用默认Any导出,否则失败。
- [DllExport("FuncName")]属性上必须指定方法名称,不指定名称虽然不报错,但导出仍有问题。
- 可以用dependencywalker工具检查有没有导出成功,能用ILSpy之类的工具打开也并不代表不能用,非托管信息是额外加的。
- 中文操作系统build可能会报错。
2.使用流程
第一步先创建一个.NetFramework的dll工程,然后去Nuget下载插件UnmanagedExports
第二步修改发布平台为x64。
然后编写测试代码,注意只能是静态方法:
namespace ClassLibrary2 { public class Class1 { [DllExport("InvokeFuncPtr")] public static void InvokeFuncPtr(Action arg) { arg(); } } }
参数是函数指针也是可以的。
第三步,UE C++部分,.h文件里先定义函数指针签名
测试类.h文件:
typedef void(*pTypeMyAction)(); typedef int32(*pTypeInvokeFuncPtr)(pTypeMyAction Arg);
测试类.cpp文件:
FString filePath = FString("ClassLibrary2.dll");//Dll位置 if (FPaths::FileExists(filePath)) { void* DLLHandle; DLLHandle = FPlatformProcess::GetDllHandle(*filePath); if (DLLHandle != NULL) { pTypeInvokeFuncPtr DLLgetAdd = NULL; DLLgetAdd = (pTypeInvokeFuncPtr)FPlatformProcess::GetDllExport(DLLHandle, *FString("InvokeFuncPtr")); if (DLLgetAdd != NULL) { DLLgetAdd([]() { UE_LOG(LogTemp, Log, TEXT("Dll load successful!")); });//调用处 } FPlatformProcess::FreeDllHandle(DLLHandle);//释放处 } }
最终打印Log,调用成功:
更多可参考github:https://github.com/3F/DllExport (好像不是一个作者,但是接口对得上)
包括传结构体等做法也可以在github页面上找到。