代码之家  ›  专栏  ›  技术社区  ›  batuman

Unity应用程序中从目标C到C的回调释放内存时出现内存问题

  •  0
  • batuman  · 技术社区  · 7 年前

    在Unity应用程序中,我需要将char*从目标C传递到C#。 现在的问题是,当使用free()释放char*时,应用程序会崩溃。

    在目标C端有一个回调函数

    Unitybridge.mm
    
    static UnityMultipleDevicesCallback MultipleDevicesLastCallBack = NULL;
    void MultipleDevicesConnectCallback(UnityMultipleDevicesCallback callbackMethod)
    {
        NSLog(@"callback is assigned");
        MultipleDevicesLastCallBack = callbackMethod;//a simple assignment using the connect method
    
    }
    
    void MultipleDevicesCallMethod(NSMutableArray *devices)
    {
        NSLog(@"devices: %@", devices);
        if(MultipleDevicesLastCallBack != NULL){
            @autoreleasepool {
               devs_ = (char*)malloc([devices count]+1 * sizeof(char));
    
               for (NSString *s in devices) {
    
                   if(strlen(devs_) > 0){
                       const char *d = "/";
                       strcat(devs_,d);
                       strcat(devs_, [s UTF8String] );
                   }
                   else{
                       strcpy(devs_, [s UTF8String]);
                   }
    
               }           
            }
    
            MultipleDevicesLastCallBack(devs_);
    
        }
    }
    void Freedevs_()
    {
    
        if(devs_!=nullptr){
            free(devs_);
            NSLog(@"devs_ is free now");
        }
    
    }
    

    在C侧,

         //
        [DllImport ("__Internal")]
        private static extern void Freedevs_();
        //Callback
        public delegate void UnityMultipleDevicesCallbackDelegate(string devices);
        [DllImport ("__Internal")]
        public static extern void MultipleDevicesConnectCallback(UnityMultipleDevicesCallbackDelegate callbackMethod);
        [MonoPInvokeCallback(typeof(UnityMultipleDevicesCallbackDelegate))]
        private static void MultipleDevicesCallback(string devices)
        {
    
            BLEdevices = (String)devices.Clone();
            Debug.Log ("Multiple devices callback now " + BLEdevices);
            //Freedevs_ ();
        }
    

    我尝试了两种选择。一个是 @autoreleasepool 第二个是不使用 @自动释放池 ,我打电话 void Freedevs_() .

    使用 @自动释放池 ,有时不确定它是否有效,有时应用程序会崩溃。如果我调用Freedevs\uz(),应用程序肯定会崩溃。

    解决这个问题的办法是什么?

    1 回复  |  直到 7 年前
        1
  •  1
  •   batuman    7 年前

    我很幸运找到了这篇文章 here .

    根据文章,我需要使用 [MarshalAs(UnmanagedType.LPStr)] 在我的C侧并更新。请注意 I don't use malloc anymore and that is sort of not reliable thing in such usage .

        Objectiv C
        void MultipleDevicesCallMethod(NSMutableArray *devices)
        {
    
    
          if(MultipleDevicesLastCallBack != NULL){
               NSString *d = @"";
               int cnt = 0;
               for (NSString *s in devices) {
                   d = [d stringByAppendingString:s];
                   if(cnt < [devices count]-1 &&  [devices count] > 1 ){
                       d = [d stringByAppendingString:@"/"];
                       cnt++;
                   }
    
               }
               const char* devs_ =  [d cStringUsingEncoding:NSUTF8StringEncoding];
               MultipleDevicesLastCallBack(devs_);
    
    
          }       
    
        }
    
         C#
         public delegate void UnityMultipleDevicesCallbackDelegate(string devices);
        [DllImport ("__Internal", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern void MultipleDevicesConnectCallback(UnityMultipleDevicesCallbackDelegate callbackMethod);
        [MonoPInvokeCallback(typeof(UnityMultipleDevicesCallbackDelegate))]
        private static void MultipleDevicesCallback([MarshalAs(UnmanagedType.LPStr)]string devices)
        {
    
            BLEdevices = (String)devices.Clone();
            Debug.Log ("Multiple devices callback now " + BLEdevices);
            Freedevs_ ();
        }