无法使用DLLImport

时间:2017-03-14 16:26:48

标签: c# windows cordova windows-runtime windows-8.1

enter image description here

以上是我的文件夹结构。我有一个Cordova应用程序和一个Windows运行时组件 - IBscanUltimate。 include文件夹具有调用非托管IBscanUltimate.dll的C#代码。 Class1.cs是这样的:

using System;
namespace IBscanUltimate
{
    public sealed class Class1
    {
        public static String getSDK()
        {
            IBscanUltimate.DLL.IBSU_SdkVersion a = new DLL.IBSU_SdkVersion();
            IBscanUltimate.DLL._IBSU_GetSDKVersion(ref a);
            return "SDKVersion: " + a;
        }
}

IBScanUltimateApi.cs& _IBSU_GetSDKVersion看起来像这样:

internal partial class DLL
{
    [DllImport("IBScanUltimate.DLL")]
    private static extern int IBSU_GetSDKVersion(ref IBSU_SdkVersion pVerinfo);
    public static int _IBSU_GetSDKVersion(ref IBSU_SdkVersion pVerinfo)
    {
        int nRc = IBSU_STATUS_OK;
        nRc = IBSU_GetSDKVersion(ref pVerinfo);
        return nRc;
    }
}

enter image description here

我已将DLL放置在许多位置,以查看它是否会被拾取并且它们都具有上述属性。但是当我尝试运行我的应用程序时,它说无法找到IBScanUltimate.DLL

这就是输出的来源:

enter image description here

enter image description here

我不确定我做错了什么,为什么DLLImport找不到我的dll。谢谢你的帮助。

确切错误是:

System.DllNotFoundException: Unable to load DLL 'IBScanUltimate.DLL': The specified module could not be found. (Exception from HRESULT: 0x8007007E)

更新#1: 我遇到过https://msdn.microsoft.com/en-us/library/windows/desktop/hh447159(v=vs.85).aspx本文解释了LoadPackagedLibrary函数可用于加载dll。我没有看到任何关于如何在C#中使用它的例子。

更新#2: Specify the search path for DllImport in .NET提到可以使用SetDllDirectoryAddDllDirectory。他有SetDllDirectory的代码段,但参数为string[] paths。我如何指定相对参数?

更新#3:

[DllImport("kernel32.dll", SetLastError = true)]
static extern bool SetDllDirectory(string lpPathName);
public static bool setPath(String path)
{
    //Windows.Storage.
    //return SetDllDirectory("ms-appx:///");
    return SetDllDirectory(path);
}

我尝试使用我的应用可以访问的各种位置调用SetDllDirectory(path)方法,但我一直在" false"。我尝试的几个例子:

NativeMethods.setPath(Package.Current.InstalledLocation.Path.ToString());
StorageFolder localFolder = Windows.Storage.ApplicationData.Current.LocalFolder;
StorageFolder folder = Windows.Storage.KnownFolders.MusicLibrary;

这是我的应用安装的地方: C:\Users\AAA\App\hello\platforms\windows\build\windows\Debug\x64\AppX 我可以看到我的DLL就在那里。但我仍然得到无法找到DLL的异常。我是否必须在清单上加上一些内容?

更新#4: 我在DLL上运行了一个dumpbin,我在dumpbin中看到了下面的DLL:

WINUSB.DLL
mfc90.dll
MSVCR90.dll
KERNEL32.dll
USER32.dll
GDI32.dll
VERSION.dll
MSVCP90.dll
SETUPAPI.dll

我想我想分别检查上面的每个dll,看看我的Windows运行时是否可以选择它?其中一个可能是没有加载的罪魁祸首?

更新#5: 在看到 Peter Torr - MSFT 的答案,并在Google上搜索MFC后,我发现了这篇文章https://msdn.microsoft.com/en-us/library/d06h2x6e.aspx,其中指出:

The MFC classes and their members cannot be used in applications that execute in the Windows Runtime.

我想现在就结束这场疯狂的狩猎。我会关闭它,我试图加载的库依赖于不适用于Windows运行时的库。 我有这种感觉,因为Windows窗体应用程序会运行,但转换为Windows运行时的代码会给出找不到DLL的错误。感谢彼得指导正确的方向。

2 个答案:

答案 0 :(得分:1)

您尝试加载的DLL显然是为桌面应用程序构建的(它具有用户,GDI和MFC导入),并且不能用作UWP二进制文件。我还怀疑DLL没有设置AppContainer标志(您传递给链接器的选项)。您需要找到另一种方法来完成您的需求(如有必要,请通过the Windows Platform UserVoice发出任何功能请求。

答案 1 :(得分:0)

我怀疑它可以很好地找到你的DLL,但它无法找到一个或多个依赖项。不幸的是,这两种情况都会导致非常通用的DllNotFoundException,它会提到您尝试P / Invoke的DLL。

有一种简单的方法可以找出遗漏的东西! Windows包含一个名为“loader snaps”的功能,启用该功能后,将记录Windows DLL加载程序为您的进程执行的所有操作。这意味着它还将打印无法加载的DLL。要启用它,请在管理员命令提示符下运行:

gflags.exe -i "<executableName>.exe" +sls

其中可执行文件名称只是没有该文件夹的可执行文件的名称。要查看输出,您还需要启用本机或混合模式调试器。您可以在Visual Studio中的项目属性调试选项卡中执行此操作。

您可以在此处详细了解负载快照:

https://blogs.msdn.microsoft.com/junfeng/2006/11/20/debugging-loadlibrary-failures/