【问题标题】:custom implementation of iTunesMobileDevice.dll throws NullReferenceExceptioniTunesMobileDevice.dll 的自定义实现抛出 NullReferenceException
【发布时间】:2014-12-04 00:53:29
【问题描述】:

我曾打算实现 Manzana.dll 库以检测 iPhone 连接事件并与设备交互。问题是它似乎只有在客户端机器安装了 iTunes dll 和资源时才有效,我不能依赖这些。因此,我尝试使用 Manzana 源代码的自定义实现来指向它对我包含在项目中的必要 iTunes 文件的引用。

虽然看起来一切正常,但在我的应用程序中使用编译库时会引发 NullReferenceException。应用程序加载并初始化正常,但是当连接 iPhone 时,connectedevent 会抛出异常。

实际错误是:

System.TypeInitializationException: The type initializer for 'istreamwrapper.MobileDevice' threw an exception. ---> System.NullReferenceException: Object reference not set to an instance of an object.
at istreamwrapper.MobileDevice..cctor()
--- End of inner exception stack trace ---
at istreamwrapper.MobileDevice.AMDeviceNotificationSubscribe(DeviceNotificationCallback callback, UInt32 unused1, UInt32 unused2, UInt32 unused3, Void*& am_device_notification_ptr)
at istreamwrapper.iPhone.doConstruction()

我能够使用它来将问题从我的 iPhone 类中缩小到此方法

private unsafe void doConstruction()
    {
        void* voidPtr;
        this.dnc = new DeviceNotificationCallback(this.NotifyCallback);
        this.drn1 = new DeviceRestoreNotificationCallback(this.DfuConnectCallback);
        this.drn2 = new DeviceRestoreNotificationCallback(this.RecoveryConnectCallback);
        this.drn3 = new DeviceRestoreNotificationCallback(this.DfuDisconnectCallback);
        this.drn4 = new DeviceRestoreNotificationCallback(this.RecoveryDisconnectCallback);
        int num = MobileDevice.AMDeviceNotificationSubscribe(this.dnc, 0, 0, 0, out voidPtr);
        if (num != 0)
        {
            throw new Exception("AMDeviceNotificationSubscribe failed with error " + num);
        }
        num = MobileDevice.AMRestoreRegisterForDeviceNotifications(this.drn1, this.drn2, this.drn3, this.drn4, 0, null);
        if (num != 0)
        {
            throw new Exception("AMRestoreRegisterForDeviceNotifications failed with error " + num);
        }
        this.current_directory = "/";               
        }
    }

问题来自于

num = MobileDevice.AMDeviceNotificationSubscribe(this.dnc, 0, 0, 0, out voidPtr);

它指向位于我的 MobileDevice 类中的代码

 [DllImport("iTunesMobileDevice.dll", CallingConvention = CallingConvention.Cdecl)]
    public static unsafe extern int AMDeviceNotificationSubscribe(DeviceNotificationCallback callback, uint unused1, uint unused2, uint unused3, out void* am_device_notification_ptr);

这似乎又在它自己的类中引用了这个

namespace istreamwrapper
{
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void DeviceNotificationCallback(ref AMDeviceNotificationCallbackInfo callback_info);
}

然后指向另一个类:

namespace istreamwrapper
{
[StructLayout(LayoutKind.Sequential, Pack = 1)]
internal struct AMDeviceNotificationCallbackInfo
  {
    internal unsafe void* dev_ptr;
    public NotificationMessage msg;

    public unsafe void* dev
    {
        get
        {
            return this.dev_ptr;
        }
    }
  }
}

大部分代码是直接从 Manzana.dll 复制的,我唯一更改的是 itunesmobiledevice 文件所在的位置(现在是设置路径,而不是在运行时检测到)

旧代码:

namespace Manzana
{
  internal class MobileDevice
  {
private static readonly FileInfo iTunesMobileDeviceFile = new FileInfo(Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\Apple Inc.\\Apple Mobile Device Support\\Shared", "iTunesMobileDeviceDLL", (object) "iTunesMobileDevice.dll").ToString());
private static readonly DirectoryInfo ApplicationSupportDirectory = new DirectoryInfo(Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\Apple Inc.\\Apple Application Support", "InstallDir", (object) Environment.CurrentDirectory).ToString());
private const string DLLName = "iTunesMobileDevice.dll";

static MobileDevice()
{
  string str = MobileDevice.iTunesMobileDeviceFile.DirectoryName;
  if (!MobileDevice.iTunesMobileDeviceFile.Exists)
  {
    str = Environment.GetFolderPath(Environment.SpecialFolder.CommonProgramFiles) + "\\Apple\\Mobile Device Support\\bin";
    if (!File.Exists(str + "\\iTunesMobileDevice.dll"))
      str = "C:\\Program Files\\Common Files\\Apple\\Mobile Device Support";
  }
  Environment.SetEnvironmentVariable("Path", string.Join(";", new string[3]
  {
    Environment.GetEnvironmentVariable("Path"),
    str,
    MobileDevice.ApplicationSupportDirectory.FullName
  }));
}

新代码:

namespace istreamwrapper
{
class MobileDevice
{
    static MobileDevice()
    {

       string str = "[XX_MYPATHHERE_XX]\\Apple\\Mobile Device Support";
       string AppSuppDirectory = @"[XX_MYPATHHERE_XX]\Apple\Apple Application Support";
       Environment.SetEnvironmentVariable("Path", string.Join(";", new string[3] { Environment.GetEnvironmentVariable("Path"), str, AppSuppDirectory }));

    }

我缺少什么导致该调用返回 null 吗?我承认我并不完全理解上面代码中发生的所有事情,所以完全有可能它很简单。

【问题讨论】:

  • 其实我可能已经解决了。我不知道为什么它会抛出一个通用的空异常,但我把那个代码拿出来并单独测试它给了我一个 dllnotfound 错误,这更有帮助。我已经更改了一条路径,明天将进行测试,看看是否解决了它。
  • 我也在找同样的东西你能帮我吗...

标签: c# iphone itunes dllimport mobile-devices


【解决方案1】:

是的,我相信答案确实是路径不正确,因此找不到文件。我只是没有意识到这一点,因为它抛出的错误太笼统了。

【讨论】:

    猜你喜欢
    • 2013-10-19
    • 2018-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-07
    • 1970-01-01
    • 2013-05-30
    • 1970-01-01
    相关资源
    最近更新 更多