首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用DiskArbitration框架安装磁盘

使用DiskArbitration框架安装磁盘
EN

Code Review用户
提问于 2016-03-24 18:57:48
回答 2查看 1.3K关注 0票数 5

下面的代码使用DiskArbitration框架将磁盘挂载到其默认位置:

代码语言:javascript
复制
#import <CoreFoundation/CoreFoundation.h>
#import <DiskArbitration/DiskArbitration.h>

void MountCallback(DADiskRef disk, DADissenterRef dissenter, void *context);

int main(int argc, const char *argv[]) {
  if (argc != 2) {
    fprintf(stderr, "Usage: %s <disk>\n", argv[0]);
    return EXIT_FAILURE;
  }

  const char *deviceName = argv[1];

  DASessionRef session = DASessionCreate(kCFAllocatorDefault);
  DADiskRef disk = DADiskCreateFromBSDName(kCFAllocatorDefault, session, deviceName);

  // Pass NULL for a "standard" mount path.
  DADiskMount(disk, NULL, kDADiskMountOptionWhole, MountCallback, (void *)deviceName);

  DASessionSetDispatchQueue(session, NULL);
  CFRelease(session);
  session = NULL;

  return EXIT_SUCCESS;
}

void MountCallback(DADiskRef disk, DADissenterRef dissenter, void *context) {
  const char *mountedDisk = context;
  fprintf(stderr, "Device mounted: %s\n", mountedDisk);
  fflush(stderr);
  return;
}

要编译代码:

代码语言:javascript
复制
clang -Wall -Werror -g -v main.m -lobjc -framework DiskArbitration -framework Foundation -o mount

要运行该程序:

代码语言:javascript
复制
./mount diskN

该程序运行良好,但作为一个对Apple平台不太了解的开发人员,我对以下几点感兴趣:

  • MountCallback函数似乎没有被调用。我没有看到我打印给stderr的那条线。
  • 如果挂载操作失败,如何访问错误,并使用它在main上返回不同的退出状态?(我假设错误是从回调中捕获的,但找不到有关它的文档)。
  • 我是否正确地释放了用于该任务的会话和其他资源?
EN

回答 2

Code Review用户

发布于 2019-02-19 09:32:52

几年后,您不是C专家;据我所知(我自己使用Pascal ),您的应用程序需要等待回调的发生。但是,从外观上看(同样是:不是专家),您的应用程序可能在回调实际发生之前已经关闭/完成。

票数 2
EN

Code Review用户

发布于 2019-02-19 18:48:01

您的代码中缺少了两样东西。正如@Hanza增塑剂所提到的,您需要等待回调的执行。其次,您需要向DASessionSetDispatchQueue()传递一个有效的队列。如果您像在代码中那样传递NULL,您将告诉它取消会话的日程安排。

您可以使用dispatch_semaphore_t在线程之间等待。把这些都放在一起,我就明白了:

代码语言:javascript
复制
#include <stdio.h>
#import <CoreFoundation/CoreFoundation.h>
#import <DiskArbitration/DiskArbitration.h>

static dispatch_semaphore_t semaphore;

void MountCallback(DADiskRef disk, DADissenterRef dissenter, void *context);

int main(int argc, const char *argv[]) {
    if (argc != 2) {
        fprintf(stderr, "Usage: %s <disk>\n", argv[0]);
        return EXIT_FAILURE;
    }

    const char *deviceName = argv[1];

    // Create the semaphore we'll wait on.
    semaphore = dispatch_semaphore_create(0);

    DASessionRef session = DASessionCreate(kCFAllocatorDefault);
    DADiskRef disk = DADiskCreateFromBSDName(kCFAllocatorDefault, session, deviceName);

    // Pass NULL for a "standard" mount path.
    DADiskMount(disk, NULL, kDADiskMountOptionWhole, MountCallback, (void *)deviceName);

    // We'll pass the global concurrent queue here so it gets executed in the background
    DASessionSetDispatchQueue(session, dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0));
    CFRelease(session);
    session = NULL;

    // Wait for the callback to signal that it's done
    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
    // Clean up
    dispatch_release(semaphore);

    return EXIT_SUCCESS;
}

void MountCallback(DADiskRef disk, DADissenterRef dissenter, void *context) {
    const char *mountedDisk = context;
    fprintf(stderr, "Device mounted: %s\n", mountedDisk);
    fflush(stderr);

    // Tell the main thread that we've finished up.
    dispatch_semaphore_signal(semaphore);
    return;
}

还有一个建议--我会把用法改为<device>,而不是<disk>。我还不清楚我是否应该在里面有"Macintosh“(磁盘名)或"disk5s1”(设备名)之类的东西。在我看来应该是设备的名字,对吧?

票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/123791

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档