I need to pass char* from Objective C to C# in Unity application. The issue now is when char* is released using free(), the application crash.
I have a callback function in Objective C side as
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");
}
}
At C# side,
//
[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_ ();
}
I tried two options. One is @autoreleasepool
and second one is without using @autoreleasepool
, I call void Freedevs_()
.
Using @autoreleasepool
, not sure sometimes it works and sometimes the application crash. If I call Freedevs_ (), definitely the application crash.
What could be the solution for this?
I am fortunate that I found this article here .
According the article, I need to use [MarshalAs(UnmanagedType.LPStr)]
at my C# side and updated. Please note that 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_ ();
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.