下面的代码使用DiskArbitration框架将磁盘挂载到其默认位置:
#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;
}要编译代码:
clang -Wall -Werror -g -v main.m -lobjc -framework DiskArbitration -framework Foundation -o mount要运行该程序:
./mount diskN该程序运行良好,但作为一个对Apple平台不太了解的开发人员,我对以下几点感兴趣:
MountCallback函数似乎没有被调用。我没有看到我打印给stderr的那条线。main上返回不同的退出状态?(我假设错误是从回调中捕获的,但找不到有关它的文档)。发布于 2019-02-19 09:32:52
几年后,您不是C专家;据我所知(我自己使用Pascal ),您的应用程序需要等待回调的发生。但是,从外观上看(同样是:不是专家),您的应用程序可能在回调实际发生之前已经关闭/完成。
发布于 2019-02-19 18:48:01
您的代码中缺少了两样东西。正如@Hanza增塑剂所提到的,您需要等待回调的执行。其次,您需要向DASessionSetDispatchQueue()传递一个有效的队列。如果您像在代码中那样传递NULL,您将告诉它取消会话的日程安排。
您可以使用dispatch_semaphore_t在线程之间等待。把这些都放在一起,我就明白了:
#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”(设备名)之类的东西。在我看来应该是设备的名字,对吧?
https://codereview.stackexchange.com/questions/123791
复制相似问题