Closed aswinthomas closed 9 years ago
without looking at your exact code, i'd just say "probably" :) as I'm not sure exactly what you're trying to do. in the context of the example project, what i think you're looking to do is create a "recurring callback" type of call where when you call up you are setting local members.
if you'd like to post an example of what's going wrong i'd be happy to give you some more specific feedback.
Sorry about that. I dont actually have the exact code at the moment since I gave up and switched to polling. Basically I used the _onetime_callback with a float argument. The only difference was this: 1) Inside the 'C' code, I make a copy of the C# function
SIMPLE_CALLBACK callback_copy;
void reply_during_call(SIMPLE_CALLBACK callback) {
if (callback) {
callback_copy=callback;
}
}
void some_other_task(){
float pi=3.14;
callback_copy(pi);
}
2) Inside the C# code, I try to set a local variable
float my_arg;
void _onetime_callback(float arg) {
my_arg = arg; // throws error
Console.WriteLine(arg); // this works well if the above line is commented
}
gotcha. no worries, i understand now. what you want in this case is to use the _recurring_callback example at https://github.com/natbro/UnityPlugin/blob/master/UnityPluginTest/Assets/Scripts/UnityPlugin.cs#L37-L48. what was happening when you received the NULL reference exception is that the little wrapper object that you were holding onto was working - it was getting you back into C# at the correct method, but the instance value was no longer valid (because you didn't have it pinned down in a member variable). using _recurring_callback and/or polling where you hold onto the delegate object (which refers to the "this" or instance object in a steady way) will allow it to work. good luck!
Perfect! Thank you
Following is my code that passes a struct. Maybe useful for others. C code:
typedef struct {
float steer;
float motor;
float brake;
int gear;
} ControlData;
ControlData *cd = new ControlData();
typedef void (*CONTROL_CALLBACK)(ControlData *cd);
CONTROL_CALLBACK controlCallbackFunction;
extern "C" int setControlCallback(CONTROL_CALLBACK callback) {
if (callback) {
printf("Setup controlCallbackFunction\n");
controlCallbackFunction = callback;
}
void task() {
//populate *cd
controlCallbackFunction(cd);
}
C# code
private delegate void ControlCallbackDelegate(ref ControlStruct value);
private ControlCallbackDelegate controlCallbackHolder;
[DllImport ("comms_interface")]
private static extern int setControlCallback(ControlCallbackDelegate callback);
[StructLayout(LayoutKind.Sequential)]
public struct ControlStruct
{
[MarshalAs(UnmanagedType.R4)]
public float targetSteer;
[MarshalAs(UnmanagedType.R4)]
public float targetMotor;
[MarshalAs(UnmanagedType.R4)]
public float targetBrake;
[MarshalAs(UnmanagedType.I4)]
public Int32 targetGear;
}
void Awake() {
controlCallbackHolder = new ControlCallbackDelegate(controlCallback);
setControlCallback(controlCallbackHolder);
}
void controlCallback(ref ControlStruct value) {
Console.WriteLine(value.targetSteer+" "+value.targetMotor+" "+
value.targetBrake+" "+value.targetGear);
}
cool, thanks for sharing & super glad it's working for you!
Will it be possible to 'set' local variables from inside the C# callback?
I get the following when I use any kind of variable. Could this be because I am storing the address of the delegate inside the 'C' file for later use?