Building DLL for Unity with functions with callback fails - unity3d

I want to build DLL for Unity with functions with callback.
When I build with X64, Callback function works.
But when I build with arm64 and deploy it on HoloLens2, it doesnot work.
Here is my code to build DLL
enter image description here
Here is my code to use it.
enter image description here
Accroding to the result shown in HoloLens. It shows "20". So the fuction "Add" runs, But callback doesnot run.
Thanks if someone can help me.

I've had some experience with native->managed callbacks in my day. Yours is simple and should work without a hitch. One thing that raises a bit of a suspicion is the calling convention of the delegate. In general calling conventions are more of a 32bit era thing. In 64bit code there is one convention so it should just be left at the default. I'd suggest you remove the explicit calling convention declarations from the attributes.
Another thing I've noticed is that squiggly green line on your screenshot. Since you already declared the callback type as typedef int (*addP)(int) why not actually use it in the function definition?
int TestAddWithCallBack(addP callback)
{
int result = Add(3,5);
return callback(result);
}
You may also want to test if the TestAddWithCallBack function is even getting called at all. Change it to:
int TestAddWithCallBack(addP callback)
{
int result = Add(3,5);
return result;
}
and see if it returns properly.

Related

Simulink code generation: function stubs from Function Caller blocks and their return values/arguments

In my Simulink model I have several Function Caller blocks like this:
Simple Function Caller block
The function prototype would simply be y = someFunction(). The output argument uses a custom enum type and is given as someEnum(1).
The output signal is defined as one-dimensional throughout.
When generating code from the model, these Function Callers have always yielded a function stub in the expected form of
extern someEnum someFunction(void);.
However, after a lot of changes recently, I've just noticed that code generation now suddenly yields function stubs in the form of
extern void someFunction(someEnum *rty_y);
for some (not all!) Function Caller blocks.
I have compared every parameter about the Function caller blocks and the related output signals that I could find but I can't find any difference between the affected ones and those working as expected in the current version or the same blocks in previous versions. All functions and signals have been renamed, but that's also true for those Function Caller blocks that are not affected.
The Code Generation options are also identical.
I have tried to understand from the help files what might cause the coder to use pointer arguments instead of direct return values for the function stubs but couldn't find anything.
Any hint at what might cause the code generator to use pointers would be greatly appreciated.
Found the problem. Some of the affected blocks had their C/C++ return argument set to "void" in their "Configure C/C++ Function Interface" dialog.
Some of the affected blocks (unfortunately, both of those I had checked before as well) were still set to "y" here and I had to change the setting to "void" and back to "y" before it yielded the desired result.

stm32f4 HardFault_Handler - need debugging advice

I'm working on a project based on the stm32f4discovery board using IAR Embedded Workbench (though I'm very close to the 32kb limit on the free version so I'll have to find something else soon). This is a learning project for me and so far I've been able to solve most of my issues with a few google searches and a lot of trial and error. But this is the first time I've encountered a run-time error that doesn't appear to be caused by a problem with my logic and I'm pretty stuck. Any general debugging strategy advice is welcome.
So here's what happens. I have an interrupt on a button; each time the button is pressed, the callback function runs my void cal_acc(uint16_t* data) function defined in stm32f4xx_it.c. This function gathers some data, and on the 6th press, it calls my void gn(float32_t* data, float32_t* beta) function. Eventually, two functions are called, gn_resids and gn_jacobian. The functions are very similar in structure. Both take in 3 pointers to 3 arrays of floats and then modify the values of the first array based on the second two. Unfortunately, when the second function gn_jacobian exits, I get the HardFault.
Please look at the link (code structure) for a picture showing how the program runs up to the fault.
Thank you very much! I appreciate any advice or guidance you can give me,
-Ben
Extra info that might be helpful below:
Running in debug mode, I can step into the function and run through all the lines click by click and it's OK. But as soon as I run the last line and it should exit and move on to the next line in the function where it was called, it crashes. I have also tried rearranging the order of the calls around this function and it is always this one that crashes.
I had been getting a similar crash on the first function gn_resids when one of the input pointers pointed to an array that was not defined as "static". But now all the arrays are static and I'm quite confused - especially since I can't tell what is different between the gn_resids function that works and the gn_jacobian function that does not work.
acc1beta is declared as a float array at the beginning of main.c and then also as extern float32_t acc1beta[6] at the top of stm32f4xx_it.c. I want it as a global variable; there is probably a better way to do this, but it's been working so far with many other variables defined in the same way.
Here's a screenshot of what I see when it crashes during debug (after I pause the session) IAR view at crash
EDIT: I changed the code of gn_step to look like this for a test so that it just runs gn_resids twice and it crashes as soon as it gets to the second call - I can't even step into it. gn_jacobian is not the problem.
void gn_step(float32_t* data, float32_t* beta) {
static float32_t resids[120];
gn_resids(resids, data, beta);
arm_matrix_instance_f32 R;
arm_mat_init_f32(&R, 120, 1, resids);
// static float32_t J_f32[720];
// gn_jacobian(J_f32, data, beta);
static float32_t J_f32[120];
gn_resids(J_f32, data, beta);
arm_matrix_instance_f32 J;
arm_mat_init_f32(&J, 120, 1, J_f32);
Hardfaults on Cortex M devices can be generated by various error conditions, for example:
Access of data outside valid memory
Invalid instructions
Division by zero
It is possible to gather information about the source of the hardfault by looking into some processor registers. IAR provides a debugger macro that helps to automate that process. It can be found in the IAR installation directory arm\config\debugger\ARM\vector_catch.mac. Please refer to this IAR Technical Note on Debugging Hardfaults for details on using this macro.
Depending on the type of the hardfault that occurs in your program you should try to narrow down the root cause within the debugger.

LibOpenCM3 vector table is all blocking-handler

The answer to this question here
Libopencm3 interrupt table on STM32F4
explains the whole mechanism nicely but what I get is whole vector table filled with blocking handlers.
I know that because I see it in debugger (apart from the whole thing not working): disassembly screenshot showing vector table.
It is as though linker simply ignores my nicely defined interrupt handler function(s), e.g.:
void sys_tick_handler(void)
{
...
}
void tim1_up_isr(void)
{
...
}
I am using EmBitz IDE and have followed this tutorial here to get libopencm3 to work (and it does work except for this issue).
I have checked the function names n-fold and have tried several online examples including those from the libopencm3-examples project.
Everything compiles without a glitch and loads into the target board (STM32F103C8) and runs fine - except no ISRs get invoked (I do get interrupt(s) but they get stuck in blocking handlers).
Does anyone have an idea why is this happening?
It looks like linking with standard vector table (from ST's SPL or HAL).
To check this, try to rename your sys_tick_handler() to SysTick_Handler() and
tim1_up_isr() to TIM1_UP_IRQHandler().
If it works, find file with this SysTick_Handler and TIM1_UP_IRQHandler (I think, that will be startup*.s) and delete it from your project.

Scriptable Plugin, Javascript returns undefined

Im trying to write a scritable plugin and I am using mozilla's example below as my guide, as well as looking at firebreath to see how it wraps the code. I am getting stuck on the return value to javascript.
Mozilla scriptable example
When javascript calls my function the Allocate,HasProperty,HasMethod,Invoke all get called. I return back the result in Invoke and the javascript variable is undefined or crashes the browser when modifying the result.
STRINGZ_TO_NPVARIANT(_strdup("Hello World"), *result);
STRINGZ_TO_NPVARIANT is actually a bit dangerous; when you put a string into an NPVariant object you give ownership of that memory to the browser. However, if you didn't allocate that memory with NPN_MemAlloc things may explode when it tries to release that memory (possibly the source of your crash).
Look at what STRINGZ_TO_NPVARIANT is actually doing and don't use it 'til you understand how it works; until then, you may try performing the steps by hand so you have a better understanding. Allocate memory using NPN_MemAlloc and then strcpy your string to it. I bet this fixes your problem; after you've got it figured out build your own inline functions or whatnot to clean up the code again.

Rhino Mocks Calling instead of Recording in NUnit

I am trying to write unit tests for a bit of code involving Events. Since I need to raise an event at will, I've decided to rely upon RhinoMocks to do so for me, and then make sure that the results of the events being raised are as expected (when they click a button, values should change in a predictable manner, in this example, the height of the object should decrease)
So, I do a bit of research and realize I need an Event Raiser for the event in question. Then it's as simple as calling eventraiser.Raise(); and we're good.
The code for obtaining an event raiser I've written as is follows (written in C#) (more or less copied straight off the net)
using (mocks.Record())
{
MyControl testing = mocks.DynamicMock<MyControl>();
testing.Controls.Find("MainLabel",false)[0].Click += null;
LastCall.IgnoreArguments();
LastCall.Constraints(Rhino.Mocks.Constraints.Is.NotNull());
Raiser1 = LastCall.GetEventRaiser();
}
I then test it as In playback mode.
using (mocks.Playback())
{
MyControl thingy = new MyControl();
int temp=thingy.Size.Height;
Raiser1.Raise();
Assert.Greater(temp, thingy.Size.Height);
}
The problem is, when I run these tests through NUnit, it fails. It throws an exception at the line testing.Controls.Find("MainLabel",false)[0].Click += null; which complains about trying to add null to the event listener. Specifically, "System.NullReferenceException: Object Reference not set to an instance of the Object"
Now, I was under the understanding that any code under the Mocks.Record heading wouldn't actually be called, it would instead create expectations for code calls in the playback. However, this is the second instance where I've had a problem like this (the first problem involved classes/cases that where a lot more complicated) Where it appears in NUnit that the code is actually being called normally instead of creating expectations. I am curious if anyone can point out what I am doing wrong. Or an alternative way to solve the core issue.
I'm not sure, but you might get that behaviour if you haven't made the event virtual in MyControl. If methods, events, or properties aren't virtual, then I don't think DynamicMock can replace their behaviour with recording and playback versions.
Personally, I like to define interfaces for the classes I'm going to mock out and then mock the interface. That way, I'm sure to avoid this kind of problem.