【发布时间】:2018-11-26 20:31:52
【问题描述】:
Here 或here 完整版本,您可以找到适用于 Unity 的示例 GRPC“Hello World”项目。只有为 Unity 构建并包装在 DLL 中的第一个版本在 Unity IDE 和 Standalone build 中完美运行fine。 Raw Grpc.Core 文件在 IDE 中正确引用了所有内容,但它们存在编组问题。
不幸的是,它无法为带有 IL2CPP 后端的 UWP 构建。 Unity 构建项目并创建一个 .sln 项目。但是 Visual Studio 总是在最终编译时为 GRPC 属性提供 LNK2001。
这里是第一个错误代码:
LNK2001 unresolved external _grpccsharp_init@0
LNK2001 unresolved external _grpccsharp_shutdonw@0
LNK2001 unresolved external _grpccsharp_version_string@0
...
好的,感谢@Sunius,我更深入地研究了它。有几点,我要补充一下问题:
在 GRPC C# 包中引用 extern 方法有两种方法。它们被命名为 static 和 shared 库。
internal class DllImportsFromStaticLib
{
private const string ImportName = "__Internal";
[DllImport(ImportName)]
public static extern void grpcsharp_init();
[DllImport(ImportName)]
public static extern void grpcsharp_shutdown();
...
}
和
internal class DllImportsFromSharedLib
{
private const string ImportName = "grpc_csharp_ext";
[DllImport(ImportName)]
public static extern void grpcsharp_init();
[DllImport(ImportName)]
public static extern void grpcsharp_shutdown();
...
}
我尝试使用共享文件对其进行测试,但我得到了另一个链接错误文件,它有点不同。
LNK2001 unresolved external _dlopen@8
LNK2001 unresolved external _dlsym@8
...
在两个单独的方法中,外部方法连接到内部接口:
public NativeMethods(DllImportsFromStaticLib unusedInstance)
{
this.grpccsharp_init = DllImportsFromStaticLib.grpccsharp_init;
this.grpccsharp_shutdown = DllImportsFromStaticLib.grpccsharp_shutdonw;
...
}
和
public NativeMethods(DllImportsFromSharedLib unusedInstance)
{
this.grpccsharp_init = DllImportsFromSharedLib.grpccsharp_init;
this.grpccsharp_shutdown = DllImportsFromSharedLib.grpccsharp_shutdonw;
...
}
这里定义了调用哪个方法:
private static NativMethods LoadNativeMethodsUnity()
{
switch(PlatformApis.GetUnityRuntimePlatform())
{
case "IPhonePlayer":
return new NativeMethods(new NativeMethods.DllImportsFromStaticLib());
default:
return new NativeMethods(new NativeMethods.DllImportsFromSharedLib());
}
}
一些更新:
感谢@jsmouret,his Grpc Github 中有 Stub.c 文件,其中包含虚假方法,因此 Linker 不再抱怨 Grpc_init 方法。
下一个错误:dlopen、dlsym、dlerror:
首先,我尝试使用相同的 Stub 技术,但在这种情况下它没有帮助,或者我做错了。
感谢@Sunius,我注释掉了所有“__Internal”dll 导入代码。所以我没有收到任何 dlopen、dlsym 和 dlerror 错误。
下一个错误:它发生在应用程序内部,而不是 Visual Studio 调试器。它告诉我:“异常:要编组托管方法,请在方法定义中添加一个名为 'MonoPInvokeCallback' 的属性。”
exception: error loading the embedded resource "Grpc.Core.roots.pem"
和
exception: To marshal a managed method, please add an attribute named 'MonoPInvokeCallback' to the method definition.
在我用谷歌搜索之后,我知道了我的选择,但问题是,我应该使用哪种方法?!
【问题讨论】:
-
考虑编辑这个问题和下面的答案,以用文本代替/替换错误消息和代码的屏幕截图。文本更易于阅读、可编入索引且更易于访问。
-
@chwarr 感谢您的评论。我会处理的。
标签: visual-studio unity3d uwp grpc il2cpp