Native Extensions

Nice! Take it for a spin and let us know how it works out for you!

2 Likes

Some small news, we’ve finally started on the Windows support for Native Extensions! \o/

Have a nice weekend! :beers: :sunny: :tropical_drink: :sunglasses:

8 Likes

Hi @sven , @Mathias_Westerdahl I have an issue and I wasted a whole day trying to understand whats wrong… and… nothing…
I really need your help.
Did you try to use callbacks with android native extensions?
I have a problem with my DefUnityAds extension on Android (On iOS it works without any problems)

It crashes in situation when I try to recieve few callbacks.
It is easy to reproduce with standart DefUnityAds example:

  • just run an example on android
  • then tap to Initialize button
  • then fast tap 2-3 times to ShowAd button.

On iOS it receives few errors by callback - it is internal error of ads skd like “not initialized” and so on… it’s ok.
But on Android it crashes.

The crash is in lua part, something like:

Build fingerprint: 'Xiaomi/nikel/nikel:6.0/MRA58K/V8.2.1.0.MBFMIDL:user/release-keys'
Revision: '0'
ABI: 'arm'
pid: 14358, tid: 14373, name: Thread-13844  >>> com.agulev.test <<<
signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------
Abort message: '../src/gameobject/comp_script.cpp:212: dmGameObject::UpdateResult dmGameObject::CompScriptUpdate(const dmGameObject::ComponentsUpdateParams&): assertion "top == lua_gettop(L)" failed'
    r0 00000000  r1 00003825  r2 00000006  r3 f342c978
    r4 f342c980  r5 f342c930  r6 00000000  r7 0000010c
    r8 ee91e1d0  r9 f342c56c  sl 00000000  fp eea001b0
    ip 00000006  sp f342c4d8  lr f7184ebd  pc f71872ac  cpsr 400e0010

backtrace:
    #00 pc 000432ac  /system/lib/libc.so (tgkill+12)
    #01 pc 00040eb9  /system/lib/libc.so (pthread_kill+32)
    #02 pc 0001c81b  /system/lib/libc.so (raise+10)
    #03 pc 000199cd  /system/lib/libc.so (__libc_android_abort+34)
    #04 pc 00017580  /system/lib/libc.so (abort+4)
    #05 pc 0001b42f  /system/lib/libc.so (__libc_fatal+16)
    #06 pc 00019a55  /system/lib/libc.so (__assert2+20)
    #07 pc 000c6b2c  /data/app/com.agulev.test-1/lib/arm/libDefUnityAds.so (_ZN12dmGameObject16CompScriptUpdateERKNS_22ComponentsUpdateParamsE+212)
    #08 pc 000b5d90  /data/app/com.agulev.test-1/lib/arm/libDefUnityAds.so (_ZN12dmGameObject6UpdateEPNS_10CollectionEPKNS_13UpdateContextE+764)
    #09 pc 0009ecfc  /data/app/com.agulev.test-1/lib/arm/libDefUnityAds.so (_ZN8dmEngine4StepEPNS_6EngineE+1268)
    #10 pc 00101e5c  /data/app/com.agulev.test-1/lib/arm/libDefUnityAds.so (_ZN10dmGraphics18RunApplicationLoopEPvPFvS0_EPFiS0_E+20)
    #11 pc 000a152c  /data/app/com.agulev.test-1/lib/arm/libDefUnityAds.so (_ZN8dmEngineL7InitRunEPN15dmEngineService13EngineServiceEiPPcPFvPNS_6EngineEPvES9_S7_+168)
    #12 pc 000a15cc  /data/app/com.agulev.test-1/lib/arm/libDefUnityAds.so (_ZN8dmEngine6LaunchEiPPcPFvPNS_6EngineEPvES6_S4_+72)
    #13 pc 0009d964  /data/app/com.agulev.test-1/lib/arm/libDefUnityAds.so (_Z11engine_mainiPPc+112)
    #14 pc 0009bcb4  /data/app/com.agulev.test-1/lib/arm/libDefUnityAds.so (main+24)
    #15 pc 0023cb9c  /data/app/com.agulev.test-1/lib/arm/libDefUnityAds.so (_glfwPreMain+236)
    #16 pc 0009bcdc  /data/app/com.agulev.test-1/lib/arm/libDefUnityAds.so (android_main+20)
    #17 pc 0023d3bc  /data/app/com.agulev.test-1/lib/arm/libDefUnityAds.so (android_app_entry+176)
    #18 pc 000407bb  /system/lib/libc.so (_ZL15__pthread_startPv+30)
    #19 pc 0001a051  /system/lib/libc.so (__start_thread+6)

It is almost all time assertion problem but in different places.

I thougth that the problem is in my code, but:

  1. It works perfect on iOS;
  2. Second strange thing, I made few logs:
    dmLogInfo("top %i",top);
    lua_rawgeti(L, LUA_REGISTRYINDEX, defUtoLua->listener.m_Callback);
   	lua_rawgeti(L, LUA_REGISTRYINDEX, defUtoLua->listener.m_Self);
   	lua_pushvalue(L, -1);
    dmLogInfo("top1 %i",lua_gettop(L));
    dmScript::SetInstance(L);
    dmLogInfo("top2 %i",lua_gettop(L));
    lua_pushnumber(L, type_of_msg);
    dmLogInfo("top3 %i",lua_gettop(L));
    int count_table_elements = 1;
    if (key_2 != NULL){
        count_table_elements = 2;
    }
    lua_createtable(L, 0, count_table_elements);
    dmLogInfo("top4 %i",lua_gettop(L));
    luaL_push_pair_str_str(L, key_1, value_1);
    if (key_2 != NULL){
        luaL_push_pair_str_num(L, key_2, value_2);
    }
    dmLogInfo("top5 %i",lua_gettop(L));
    int ret = lua_pcall(L, 3, LUA_MULTRET, 0);
    dmLogInfo("top6 %i",lua_gettop(L));
    if (ret != 0) {
        dmLogError("Error running defUtoLua callback: %s", lua_tostring(L, -1));
        lua_pop(L, 1);
    }
    dmLogInfo("top7 %i",lua_gettop(L));

and receive next result:

INFO:DEFAULT: top 0
INFO:DEFAULT: top1 3
INFO:DEFAULT: top2 5 --between top1 and top2 only dmScript::SetInstance(L); - WHY STACK IS SO BIG? O_o
INFO:DEFAULT: top3 1
INFO:DEFAULT: top4 2
INFO:DEFAULT: top5 2

the same trace is on ios almost all time

INFO:DEFAULT: top1 3
INFO:DEFAULT: top2 2
INFO:DEFAULT: top3 3
INFO:DEFAULT: top4 4
INFO:DEFAULT: top5 4

On iOS I have stable trace of stack size all the time.
On Android first and second time - it’s ok, but after then it randomly changes size of stack (it is not all time place between top1 and top2).
It looks like something changing stack in other thread or something like this. I can’t explain and can’t solve this problem (

Sorry for this long post, I hope you understand what I mean.
I reread all c++/lua docs, recheck all methods and ask @britzl about lua_gettop … Nothing helps…

Hope you can help me, thank you.

1 Like

Well, to answer your first question, yes, we use callbacks in the AdMob example: googlemobileads.cpp

As for the discrepancy in the stack, I’m not sure, I’m going to read through your code when I get home tonight.
But, a tip, is to make sure you push/pop the number of expected values in each function.
See the documentation for DM_LUA_STACK_CHECK() and examples here and here

Also, sometimes when forgetting to return the correct value (number of values pushed onto the stack) from the function, it can also misbehave (e.g. crash)

1 Like

You call that small news? This is awesome!

3 Likes

Looks like I am right and the issue is in multithreading.

I see that you solved the same issue using array of MessageCommand (your own stack of callbacks) - it looks like a plan.

I’ll try to make something like this in my native extension, thank you!

I was bewildered because the same code works good on ios. But on ios all callbacks works using dispatch_async(dispatch_get_main_queue() … (in SDK) and i think that the reason why it works without any problem.
But strange that on Android all callbacks run with runOnUiThread methods (in SDK), but it not helps.

I’ll try to check thread ids and understand why it not helps.

UPD:
I made stack of callbacks and push them to lua by update method. All works fine. Thank you @Mathias_Westerdahl for the help

3 Likes

Great that you got it working!
Yes, the threading bit is important when dealing with activities. I’m not sure why your runOnUiThread didn’t work though, I know we use it in the engine for the same purpose. And, from the Android doc:

“the main thread is also sometimes called the UI thread.”

2 Likes

I don’t know too, this code into SDK (not my, it is Unity code).
I tried to run callbacks on my side using runOnUiThread and using the main looper (context.getMainLooper) - same result.

As faster and most efficien variand I choosed variant from your example, when you send all callbacks in udate method.

Trying to make FMOD minimal extension.
For FMOD universal binary libfmodL.dylib (x86, x86_64) where exactly should be placed this lib?

1 Like

We currently do not support shared libraries (.so/.dylib/.dll).
I’ll add a ticket for this tomorrow.

Edit: Added DEF-2732 for supporting dynamic libraries.

2 Likes

@Mathias_Westerdahl Thanks again for the extension, great to see a reward video running in our game. A little things that was left out of the admob README was to add the
[admob]
app_id_android = dfae91c47dbd4fa08322e1092bdc1f1c
app_id_ios = ca-app-pub-3940256099942544~1458002511
to the game.project . Took me a while to figure out that this was the thing missing for the ads to work on a different project, so i guess it would be a nice edition to the instructions.

2 Likes

Ah, good point! It slipped my mind :confused:
I’ll add it right away, thanks!

1 Like

For those of you eager to try out our new HTML5 support for native extensions in 1.2.105, I’ve uploaded our example app.

Also note that we’ve added a new html5 module, with a simple run function html5.run(). This should help those that need something more light weight.

5 Likes

Perhaps someone might know why I’m not receiving the MESSAGE_REWARD callback on android? Managed to get the admob rewarded videos complete working on ios, however, on android 7 rewarded videos crash after finishing and on older android devices I seem to be missing the MESSAGE_REWARD callback.

Hmm, not sure unfortunately. I’ve been using an Android 7 to test these things. I’ll check an older version too to see if I see any difference.

The example works fine on older androids, however, after implementing the library to our project the MESSAGE_REWARD callback is only working on ios. Could it be that I missed something specific with android that could affect the callback?

Hmm, could it be related to any changes in AndroidManifest.xml?

So far i only changed the com.defold.adtest to my package name so it should be fine unless there’s something more i need to change.

Well, you probably need to change the Firebase related stuff as well: AndroidManifest.xml:L122

Yeah I believe I have all the necessary firebase stuff changed