我有一个可以使用 Mono c# 编译器编译的主要 C# 可执行文件,但 EXE 使用的 DLL 使用 P/Invoke 和其他不支持的单声道方法,因此我无法将此 DLL 编译为 Mono。有什么方法可以将这些 DLL 与提前编译的 Mono Executable 一起使用?
3 回答
您的问题有点含糊,因为您似乎将 AOT 和 P/Invoke 混为一谈。AOT 不会调用和缓存 P/Invoke 调用的结果,实际上它们之间没有任何关系。
AOT 基本上为 ILDASM .NET 字节码生成本机代码。它与 P/Invoke 调用无关。P/Invoke 是一个运行时 .NET 函数,它从本机 DLL 调用该函数。
与您的帖子相反,Mono 完全支持 P/Invoke。您的问题与 Mono 无关,因此 Mono AOT 无法解决您的问题。您的问题是,您在 Mono 下运行应用程序的平台不支持 P/Invoke'd 库。没有人可以在这里帮助您;您将需要为新平台重新实现本机功能或找到托管替代方案。
是的,可以 AOT 编译主可执行文件并仍然访问非 AOT 编译的库。
但是 AOT 并不是一种混淆机制,特别是您仍然需要原始的 main 可执行文件,否则您的程序将无法运行。您想要 AOT 编译可执行文件/库的唯一原因是在一些非常特定的场景中让它更快一点。
如果您想混淆,请查看mkbundle。
Mono 支持 pinvoke(如果没有,它几乎没用)。AOT 编译的代码仍然可以调用 pinvoke 方法。您将看到的问题将来自您的目标平台可能不支持的非托管 C 库(linux?mac?solaris?)
你在这里有三件事:
前两个在上面的链接中得到了充分的解释,PInvoke 是高级 .Net/Mono 编程的核心,并且得到了很好的支持。AOT 更常用于Android或iPhone目标
最后一点,您拥有的库仅在 .Net 下的 windows 上可用,通常涉及 Mono 未实现的核心框架方法(您要调用什么?)或者是 windows 系统调用的包装器(通常在 kernel32.dll ) 在 linux 或其他平台上不存在。
您可能还会发现,即使您需要的程序集似乎在单声道上运行,原始作者可能没有注意使用可移植目录分隔符之类的事情,并且一直假定为 Windows 平台。
我的建议是在你的程序上运行一个新的MoMa副本,看看它说了什么。