如何从 .m 函数获取结果到 .mm 类 Objective-C 与 Qt 混合

Posted

技术标签:

【中文标题】如何从 .m 函数获取结果到 .mm 类 Objective-C 与 Qt 混合【英文标题】:how to get result from .m function to .mm class Objective-C mixed with Qt 【发布时间】:2021-06-16 16:34:21 【问题描述】:

我有 Qt 应用程序,我正在调用 UIImagePickerController 来获取用户选择的电影的文件路径。所以我在 Objective-C 中有静态函数,它从 .m 文件中调用函数,当用户选择电影时,我可以在另一个 .m 函数中读取选定的路径。问题是,如何将此 filePath 放入某个 Objective-C 类中,我可以在其中调用另一个 Qt 类(如 Singleton)并将此结果传递给适当的类? Objective-C CL_image_call.mm

#include "cl_image_call.h"
#include "cl_image_func.h"

myCLImageClass* CL_image_obj=NULL;

int CL_ImageCCall::CL_objectiveC_Call() 
  //Objective C code calling..... 
    if( CL_image_obj==NULL ) 
      //Allocating the new object for the objective C class we created
        CL_image_obj=[[myCLImageClass alloc]init]; 
    
  return 1;

void CL_ImageCCall::CL_openMedia() 
    [CL_image_obj openMedia];

CL_image_call.h

#include <QImage>
#include <QString>
#include <QDebug>
#include <stdio.h>
#include "my_singleton.h"

class CL_ImageCCall

  public:
    static int CL_objectiveC_Call(); 
    static void CL_openMedia();  
;

CL_image_func.h

#import <Foundation/Foundation.h>
#import <CoreLocation/CoreLocation.h>
#import <CoreGraphics/CoreGraphics.h>
#import <UIKit/UIKit.h>
#import <MobileCoreServices/MobileCoreServices.h>

@interface myCLImageClass:NSObject
-(void)openMedia;
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info;
@end

CL_image_func.m

#import "cl_image_func.h"

@interface QiosViewController : UIViewController
@end

@implementation myCLImageClass
UIImagePickerController *picker=NULL;
UIViewController *viewController=NULL;
NSString *f_path;

-(void)openMedia 
    UIWindow *keyWindow = [[UIApplication sharedApplication] keyWindow];
    
    viewController = (UIViewController *)([keyWindow rootViewController]);
        if (!viewController)
            return;
    
    if([UIImagePickerController isSourceTypeAvailable:
                            UIImagePickerControllerSourceTypePhotoLibrary]) 

         picker= [[UIImagePickerController alloc] init];
         picker.delegate = self;
         picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
         picker.mediaTypes = [NSArray arrayWithObjects:(NSString *)kUTTypeMovie, nil];

         [viewController presentViewController:picker animated:YES completion:NULL];
    

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info 
    NSString *docDirPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    NSString *filePath =  [docDirPath stringByAppendingPathComponent:@"movie.mov"];
    NSLog (@"File Path = %@", filePath);
    //filePath is what I need to pass to the rest of my app
    
    [viewController dismissViewControllerAnimated:YES completion:nil];

所以在 CL_image_call.h 我有我的“my_singleton”,我可以在其中访问我的整个应用程序,但是如何获取此类的 filePath?

最好的问候

马雷克

【问题讨论】:

我猜你需要从相册中导出媒体并存储在你的沙箱中的某个地方,你可以使用filePath来访问媒体并做你想做的事? 【参考方案1】:

这是导出媒体的代码:

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info 
    NSString *docDirPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    NSString *filePath =  [docDirPath stringByAppendingPathComponent:@"movie.mov"];
    NSLog (@"File Path = %@", filePath);
    //filePath is what I need to pass to the rest of my app
    NSURL *inputURL  = [info objectForKey:UIImagePickerControllerMediaURL];
    AVURLAsset *asset = [AVURLAsset URLAssetWithURL:inputURL options:nil];
    // config the session, maybe some option is not what you need, just config by what you need
    AVAssetExportSession *session = [[AVAssetExportSession alloc] initWithAsset:asset
                                                                     presetName:AVAssetExportPresetMediumQuality];
    session.outputURL = [NSURL fileURLWithPath:filePath];
    session.outputFileType = AVFileTypeMPEG4;
    session.shouldOptimizeForNetworkUse = YES;
    [session exportAsynchronouslyWithCompletionHandler:^(void)
     
        // do a completion handler
    ];
    
    [viewController dismissViewControllerAnimated:YES completion:nil];

然后你可以通过filePath访问输出,在需要的时候使用。

【讨论】:

我想在我的答案中发布代码,而评论空间太小,我可以更改我的原始问题,包括你的答案,但我觉得这很奇怪【参考方案2】:

我已根据您的建议修改了代码,它做了它应该做的。我在我的 Qt 类中设置了 moviePath,然后我用这个路径调用了 Objective-C 代码

NSString *f_path;
  //Your objective c code here....

-(void)openMedia:(NSString*)moviePath 
    UIWindow *keyWindow = [[UIApplication sharedApplication] keyWindow];
    
    f_path=moviePath.copy;
    viewController = (UIViewController *)([keyWindow rootViewController]);
        if (!viewController)
            return;
    if([UIImagePickerController isSourceTypeAvailable:
                            UIImagePickerControllerSourceTypePhotoLibrary]) 

         picker= [[UIImagePickerController alloc] init];
         picker.delegate = self;
         picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
         picker.mediaTypes = [NSArray arrayWithObjects:(NSString *)kUTTypeMovie, nil];

         [viewController presentViewController:picker animated:YES completion:NULL];
        
    

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info 
    NSURL *inputURL  = [info objectForKey:UIImagePickerControllerMediaURL];
    AVURLAsset *asset = [AVURLAsset URLAssetWithURL:inputURL options:nil];
    // config the session, maybe some option is not what you need, just config by what you need
    AVAssetExportSession *session = [[AVAssetExportSession alloc] initWithAsset:asset
                                                                         presetName:AVAssetExportPresetMediumQuality];
    session.outputURL = [NSURL fileURLWithPath:f_path];
    session.outputFileType = AVFileTypeMPEG4;
    session.shouldOptimizeForNetworkUse = YES;
    [session exportAsynchronouslyWithCompletionHandler:^(void)
    
        // do a completion handler
        NSLog (@"export complete = %@", f_path);
    ];
    
    [viewController dismissViewControllerAnimated:YES completion:nil];

通过一些技巧,我可以在 Qt 应用程序中观看这部电影。缺少的一件事: 我需要以某种方式知道该会话已完成,以刷新 MediaPlayer 的文件路径。我如何通知我的基类 CL_ImageCCall。或者实际上可能是另一个我可以混合 Qt 和 Objective-C 的 Objective-C++ 类?

最好的问候和感谢您的帮助

马雷克

【讨论】:

block in exportAsynchronouslyWithCompletionHandler 是完成后的回调,发布通知或其他方式通知您的媒体播放器,就可以了 是的,我知道这个块会等到会话完成。也许这是与 Qt 相关的问题。我无法从 .m 文件函数访问我的 Qt/C++ 类。如果我在 CL_image_func.h 文件中添加一些内容,例如 #include "my_singleton.h"(我的 C++ 单例),编译会失败,并出现来自基本 Qt 类的 20 个错误。有没有办法例如使用一些 iOS 特定的方式来通知静态类 CL_image_call 我在哪里初始化 CL_image_obj=[[myCLImageClass alloc]init] imagePicker 已经完成? 如果我可以在 .mm 文件中编写所有 iOS 代码,对我来说也是一个解决方案。是否可以将 -(void)openMedia:(NSString*)moviePath - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info 移动到 .mm 文件中? 您是否尝试将 CL_image_func.m 重命名为 CL_image_func.mm? ***.com/questions/4562255/xcode-m-vs-mm 感谢老兄,这次改动后效果很好。最好的问候

以上是关于如何从 .m 函数获取结果到 .mm 类 Objective-C 与 Qt 混合的主要内容,如果未能解决你的问题,请参考以下文章

c#字符串日期格式从d.M.yyyy到yyyy-MM-dd

如何将标志从一个 __m256 中的浮点数复制到另一个 __m256 中? [复制]

当 ArrayList 和构造函数/获取器存储 2 个其他类时,如何从一个类添加到 ArrayList

从向量中保存的类对象输出类函数

可以从一个来源获取 3 个元素的 _mm_shuffle_ps 的替代方案?

如何从 JS 中的 Y-m-d 日期获取 unix 时间戳?