我在V8.Net中使用的技巧如下:
- 创建一个新的C# "代理接口"项目,并使用所有定义来在不同架构之间进行切换。在我的情况下,该项目名为
V8.Net-ProxyInterface
;例如:
public unsafe static class V8NetProxy
{
#if x86
[DllImport("V8_Net_Proxy_x86")]
#elif x64
[DllImport("V8_Net_Proxy_x64")]
#else
[DllImport("V8_Net_Proxy")]
#endif
public static extern NativeV8EngineProxy* CreateV8EngineProxy(bool enableDebugging, void* debugMessageDispatcher, int debugPort);
这是你需要参考的项目。请勿参考接下来的两个项目:
创建两个项目来生成库的 x64 和 x86 版本。这非常简单:只需复制和粘贴 .csproj
文件以在相同文件夹中重命名即可。在我的情况下,项目文件被重命名为 V8.Net-ProxyInterface-x64
和 V8.Net-ProxyInterface-x86
,然后将这些项目添加到我的解决方案中。在 Visual Studio 中打开每个项目的设置,并确保 Assembly Name
中包含 x64 或 x86 的名称。此时您已经有了 3 个项目:第一个“占位符”项目和两个特定于架构的项目。对于这两个新项目:
a)在 x64 接口项目设置中打开构建选项卡,在顶部选择 所有平台
作为 平台
,然后在 条件编译符号
中输入 x64
。
b)在 x86 接口项目设置中打开构建选项卡,在顶部选择 所有平台
作为 平台
,然后在 条件编译符号
中输入 x86
。
打开 构建->配置管理器...
,确保选择 x64
作为 x64 项目的平台,选择 x86
作为 x86 项目的平台,并分别在 Debug
和 Release
配置中进行设置。
确保两个新接口项目(x64 和 x86)输出到主机项目的相同位置(请参见项目设置 构建->输出路径
)。
最后的魔法:在我的引擎的静态构造函数中,我快速附加到程序集解析器:
static V8Engine()
{
AppDomain.CurrentDomain.AssemblyResolve += Resolver;
}
在
Resolver
方法中,我只是根据当前进程指示的当前平台加载文件(注意:此代码是削减版本且未经测试):
var currentExecPath = Assembly.GetExecutingAssembly().Location;
var platform = Environment.Is64BitProcess ? "x64" : "x86";
var filename = "V8.Net.Proxy.Interface." + platform + ".dll"
return Assembly.LoadFrom(Path.Combine(currentExecPath , fileName));
最后,在解决方案资源管理器中进入您的主机项目,展开引用
,选择第一个在第一步中创建的虚拟项目,在右键单击打开属性,并将复制本地
设置为false
。这样可以使用一个名称来开发每个P/Invoke函数,同时使用解析器来确定实际加载哪个。
请注意,程序集加载器仅在需要时才运行。它仅在CLR系统在首次访问引擎类时(在我的情况下)自动触发。这如何转化取决于您的主机项目是如何设计的。
DllImport
属性,并手动使用LoadLibrary
、GetProcAddess
和FreeLibrary
函数加载 DLL。该技术在 这里 中有所讨论。虽然这是相当繁琐的工作,而且很容易出错。让 P/Invoke 机制为你完成这项工作要容易得多。正如其他人所指出的那样,如果你可以始终回退到 32 位 DLL 作为最低公共分母,那么可能不值得这样做。 - Cody Gray