【发布时间】:2012-06-06 20:00:41
【问题描述】:
情况就是这样,我在我的 dot.net 应用程序中使用基于 C 的 dll。有2个dll,一个是32位的,叫MyDll32.dll,另一个是64位的,叫MyDll64.dll。
有一个静态变量保存 DLL 文件名:字符串 DLL_FILE_NAME。
它的使用方式如下:
[DllImport(DLL_FILE_NAME, CallingConvention=CallingConvention.Cdecl, EntryPoint=Func1")]
private static extern int is_Func1(int var1, int var2);
到目前为止很简单。
您可以想象,软件是在“Any CPU”开启的情况下编译的。
我还有如下代码来判断系统应该使用64位文件还是32位文件。
#if WIN64
public const string DLL_FILE_NAME = "MyDll64.dll";
#else
public const string DLL_FILE_NAME = "MyDll32.dll";
#endif
现在您应该看到问题了。DLL_FILE_NAME 是在编译时而不是在执行时定义的,因此不会根据执行上下文加载正确的 dll。
处理此问题的正确方法是什么?我不想要两个执行文件(一个用于 32 位,另一个用于 64 位)?如何设置 DLL_FILE_NAME 之前在 DllImport 语句中使用它?
【问题讨论】:
-
64 位和 32 位 dll 的区别是什么?有什么32位不能在64上做的吗?如果是这样,我只会使用 32。
-
在 64 位操作系统上,在程序执行时决定是在纯 64 位还是 WOW64(模拟 32 位)中执行代码。如果程序在 32 位模式下执行,它应该使用基于 C 的 dll,相应地在 32 位和 64 位中编译。
-
如果您真的想这样做,您需要完全绕过
DllImport属性并自己手动加载DLL,使用LoadLibrary、GetProcAddess和FreeLibrary职能。该技术在here 进行了讨论。不过,这是一项相当多的工作,而且很容易出错。让 P/Invoke 机制为您做这件事要容易得多。正如其他人所指出的那样,如果您可以一直回退到 32 位 DLL 作为最低公分母,这可能不值得。
标签: c# .net pinvoke 32bit-64bit dllimport