我原本打算实现Manzana.dll库以检测iPhone连接事件并与设备进行交互。问题在于,如果客户端计算机安装了iTunes dll和资源,它似乎只能工作,这是我不能依赖的。因此,我正在尝试使用Manzana源代码的自定义实现来指向它所包含的必要iTunes文件的引用。iTunesMobileDevice.dll的自定义实现抛出NullReferenceException
虽然一切看起来都不错,但编译的库在我的应用程序中使用时会引发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?我承认我没有完全理解上述代码中发生的一切,所以完全有可能这很简单。
其实,我可能已经解决了它。我无法弄清楚它为什么抛出一个generica null异常,但是我将这些代码分开并单独进行了测试,它给了我一个dllnotfound错误,这更有帮助。我已经改变了一条路,并且会在明天进行测试,看看它是否能解决问题。 – Chris2222000 2014-12-04 02:59:16
我也在寻找同样的事情,你能帮我吗? – 2015-01-20 08:20:12