Search Unity

Getting errors related to IL2CPP and MonoPInvokeCallback' with Steamworks

Discussion in 'Windows' started by CryptoGrounds, Jul 18, 2020.

  1. CryptoGrounds

    CryptoGrounds

    Joined:
    May 23, 2017
    Posts:
    12
    Hello, I am trying to add IAPs to my steam game. I have successfully launched my game from steam and all that however I have been struggling miserably with IAPs.

    I build:
    Windows x86_64 with IL2CPP
    Unity Version: 2019.3.0f6

    Here is my code:

    Code (CSharp):
    1. public Callback<MicroTxnAuthorizationResponse_t> m_MicroTxnAuthorizationResponse;
    2.    
    3.     private async void BuyProductID(string productId)
    4.     {
    5.         if (steam.steamEnabled)
    6.         {
    7.             //gets steam info like country code, player id etc
    8.  
    9.             m_MicroTxnAuthorizationResponse = Callback<MicroTxnAuthorizationResponse_t>.Create(OnMicroTxnAuthorizationResponse);
    10.             if (CanPurchase) BuyProductID(productId);
    11.         }
    12.     }
    13.  
    14.     private static bool CanPurchase;
    15.    
    16.     [AOT.MonoPInvokeCallback(typeof(MicroTxnAuthorizationResponse_t))]
    17.     private static async void OnMicroTxnAuthorizationResponse(MicroTxnAuthorizationResponse_t pCallback)
    18.     {
    19.         CanPurchase = pCallback.m_bAuthorized == 1;
    20.         if (pCallback.m_bAuthorized != 1) return;
    21.         Log("Authorized Payment");
    22.         const string url = "https://partner.steam-api.com/ISteamMicroTxn/FinalizeTxn/v2/?key=<key>&input_json";
    23.         var values = new FinalizeTxn(10000, <id>);
    24.         var json = new StringContent(JsonUtility.ToJson(values));
    25.         await client.PostAsync(url, json);
    26.     }
    And this is one of the errors I get in the "Player.txt" file when calling "BuyProductID()"


    Uploading Crash Report
    NotSupportedException: IL2CPP does not support marshaling delegates that point to instance methods to native code. The method we're attempting to marshal is: Steamworks.Callback`1[[Steamworks.MicroTxnAuthorizationResponse_t, Assembly-CSharp-firstpass, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]]::OnRunCallResult
    at Steamworks.Callback`1[T].BuildCCallbackBase () [0x00000] in <00000000000000000000000000000000>:0
    at Steamworks.Callback`1[T]..ctor (Steamworks.Callback`1+DispatchDelegate[T] func, System.Boolean bGameServer) [0x00000] in <00000000000000000000000000000000>:0
    at Steamworks.Callback`1[T].Create (Steamworks.Callback`1+DispatchDelegate[T] func) [0x00000] in <00000000000000000000000000000000>:0
    at GoogleMobileAds.Api.RewardedAd.remove_OnUserEarnedReward (System.EventHandler`1[TEventArgs] value) [0x00000] in <00000000000000000000000000000000>:0
    at Discord.ActivityManager+ActivityJoinHandler.Invoke (System.String secret) [0x00000] in <00000000000000000000000000000000>:0
    at System.Threading.ExecutionContext.RunInternal (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state, System.Boolean preserveSyncCtx) [0x00000] in <00000000000000000000000000000000>:0
    at System.Runtime.CompilerServices.AsyncMethodBuilderCore+MoveNextRunner.Run () [0x00000] in <00000000000000000000000000000000>:0
    at System.Action.Invoke () [0x00000] in <00000000000000000000000000000000>:0
    at Discord.ActivityManager+ActivityJoinHandler.Invoke (System.String secret) [0x00000] in <00000000000000000000000000000000>:0
    at UnityEngine.WaitForSeconds..ctor (System.Single seconds) [0x00000] in <00000000000000000000000000000000>:0
    at UnityEngine.UnitySynchronizationContext.Exec () [0x00000] in <00000000000000000000000000000000>:0
    --- End of stack trace from previous location where exception was thrown ---
    at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x00000] in <00000000000000000000000000000000>:0
    at System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.<ThrowAsync>b__6_0 (System.Object state) [0x00000] in <00000000000000000000000000000000>:0
    at Discord.ActivityManager+ActivityJoinHandler.Invoke (System.String secret) [0x00000] in <00000000000000000000000000000000>:0
    at UnityEngine.WaitForSeconds..ctor (System.Single seconds) [0x00000] in <00000000000000000000000000000000>:0
    at UnityEngine.UnitySynchronizationContext.Exec () [0x00000] in <00000000000000000000000000000000>:0
    UnityEngine.Logger:LogException(Exception, Object)
    UnityEngine.Debug:LogException(Exception)
    UnityEngine.WaitForSeconds:.ctor(Single)
    UnityEngine.UnitySynchronizationContext:Exec()


    I also have been getting this when I launch the game:

    Uploading Crash Report
    NotSupportedException: To marshal a managed method, please add an attribute named 'MonoPInvokeCallback' to the method definition. The method we're attempting to marshal is: SteamManager::SteamAPIDebugTextHook
    at Steamworks.SteamClient.SetWarningMessageHook (Steamworks.SteamAPIWarningMessageHook_t pFunction) [0x00000] in <00000000000000000000000000000000>:0
    at SteamManager.OnEnable () [0x00000] in <00000000000000000000000000000000>:0


    It appears that it started showing up after I added [AOT.MonoPInvokeCallback(typeof(MicroTxnAuthorizationResponse_t))], maybe not, I am unsure and was a little unaware till I noticed it.

    Anyone got any ideas? Thanks!
     
  2. CryptoGrounds

    CryptoGrounds

    Joined:
    May 23, 2017
    Posts:
    12
    Also, I might be doing this all completely wrong too. Steam's instructions on implementation were unclear to me.
     
  3. JoshPeterson

    JoshPeterson

    Unity Technologies

    Joined:
    Jul 21, 2014
    Posts:
    6,936
    Marshaling of async functions like this does not work. The error message here is a bit misleading, as it does not mention async, but instead thinks this is an instance method (which is incorrect, it is clearly static).

    Can you re-write OnMicroTxnAuthorizationResponse so that it is not async?
     
  4. CryptoGrounds

    CryptoGrounds

    Joined:
    May 23, 2017
    Posts:
    12
    Hello, this still occurs whether it's async or not. D:
     
  5. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,680
    Do you have source code for "Steamworks.Callback`1[T].BuildCCallbackBase ()"? Looks like it's trying to marshal a non-static function to native code there.
     
  6. CryptoGrounds

    CryptoGrounds

    Joined:
    May 23, 2017
    Posts:
    12
    should i make this static?
    Code (CSharp):
    1. // Steamworks.NET Specific
    2.         private void BuildCCallbackBase() {
    3.             m_CallbackBaseVTable = new CCallbackBaseVTable() {
    4.                 m_RunCallback = OnRunCallback,
    5.                 m_RunCallResult = OnRunCallResult,
    6.                 m_GetCallbackSizeBytes = OnGetCallbackSizeBytes
    7.             };
    8.             m_pVTable = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(CCallbackBaseVTable)));
    9.             Marshal.StructureToPtr(m_CallbackBaseVTable, m_pVTable, false);
    10.  
    11.             m_CCallbackBase = new CCallbackBase() {
    12.                 m_vfptr = m_pVTable,
    13.                 m_nCallbackFlags = 0,
    14.                 m_iCallback = CallbackIdentities.GetCallbackIdentity(typeof(T))
    15.             };
    16.             m_pCCallbackBase = GCHandle.Alloc(m_CCallbackBase, GCHandleType.Pinned);
    17.         }
    And should I make `OnMicroTxnAuthorizationResponse` non static?
     
    Last edited: Jul 21, 2020
  7. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,680
    You should make "OnRunCallback", "OnRunCallResult" and "OnGetCallbackSizeBytes" static.
     
  8. CryptoGrounds

    CryptoGrounds

    Joined:
    May 23, 2017
    Posts:
    12
    upload_2020-7-20_20-28-29.png

    should i make this field static?
     
  9. CryptoGrounds

    CryptoGrounds

    Joined:
    May 23, 2017
    Posts:
    12
    Ok I made them static and these are the errors I get:
    (also, I moved
      m_MicroTxnAuthorizationResponse = Callback<MicroTxnAuthorizationResponse_t>.Create(OnMicroTxnAuthorizationResponse);
    to the start where it initialized steamworks.

     UnloadTime: 53.471300 ms
    Uploading Crash Report
    NotSupportedException: To marshal a managed method, please add an attribute named 'MonoPInvokeCallback' to the method definition. The method we're attempting to marshal is: SteamManager::SteamAPIDebugTextHook
    at Steamworks.SteamClient.SetWarningMessageHook (Steamworks.SteamAPIWarningMessageHook_t pFunction) [0x00000] in <00000000000000000000000000000000>:0
    at SteamManager.OnEnable () [0x00000] in <00000000000000000000000000000000>:0

    (Filename: currently not available on il2cpp Line: -1)

    UnityIAP Version: 1.23.3
    0x00007FFA0DADAD7C (UnityPlayer)
    0x00007FFA0DADD823 (UnityPlayer)
    0x00007FFA0DAD2D4D (UnityPlayer)
    0x00007FFA0E373E3E (UnityPlayer) UnityMain
    0x00007FFA0DEE0CC7 (UnityPlayer) UnityMain
    0x00007FFA0CBD0992 (GameAssembly) [UnityEngine.CoreModule.cpp:26249] Logger_Log_mB522987DEE1BF780EAEC6864D34D7E285F5E8AB2
    0x00007FFA0C954A1E (GameAssembly) [Stores.cpp:34336] StandardPurchasingModule_Instance_mBFD020AAC15056A1B2FC83F818751676576D4A98
    0x00007FFA0CE916BA (GameAssembly) [Assembly-CSharp5.cpp:40202] IAPManager_InitializePurchasing_m2E0B90FC1911C935C1FB216EC8EB77014FC42B25
    0x00007FFA0CE93724 (GameAssembly) [Assembly-CSharp5.cpp:39185] IAPManager_Start_m468873CB081DE60E03D10A263F9812973E9E04AC
    0x00007FFA0C6FAB7C (GameAssembly) [Il2CppInvokerTable.cpp:25721] RuntimeInvoker_TrueVoid_t22962CB4C05B1D89B55A6E1139F0E87A90987017
    0x00007FFA0C6A4510 (GameAssembly) [Runtime.cpp:506] il2cpp::vm::Runtime::Invoke
    0x00007FFA0DE60520 (UnityPlayer) UnityMain
    0x00007FFA0DE71673 (UnityPlayer) UnityMain
    0x00007FFA0DE7B818 (UnityPlayer) UnityMain
    0x00007FFA0DE7B8AE (UnityPlayer) UnityMain
    0x00007FFA0DE7A909 (UnityPlayer) UnityMain
    0x00007FFA0DC02FCD (UnityPlayer) UnityMain
    0x00007FFA0DD47827 (UnityPlayer) UnityMain
    0x00007FFA0DD478C3 (UnityPlayer) UnityMain
    0x00007FFA0DD49CCB (UnityPlayer) UnityMain
    0x00007FFA0DB06DAE (UnityPlayer)
    0x00007FFA0DB05B0A (UnityPlayer)
    0x00007FFA0DB09AF8 (UnityPlayer)
    0x00007FFA0DB0D5AB (UnityPlayer) UnityMain
    0x00007FF7CC7D11F2 (CryptoClickers)
    0x00007FFAB20C7BD4 (KERNEL32) BaseThreadInitThunk
    0x00007FFAB33CCE51 (ntdll) RtlUserThreadStart

    (Filename: C:\buildslave\unity\build\Runtime/Export/Debug/Debug.bindings.h Line: 35)

    Uploading Crash Report
    NotSupportedException: To marshal a managed method, please add an attribute named 'MonoPInvokeCallback' to the method definition. The method we're attempting to marshal is: Steamworks.Callback`1[[Steamworks.MicroTxnAuthorizationResponse_t, Assembly-CSharp-firstpass, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]]::OnRunCallResult
    at Steamworks.Callback`1[T].BuildCCallbackBase () [0x00000] in <00000000000000000000000000000000>:0
    at Steamworks.Callback`1[T]..ctor (Steamworks.Callback`1+DispatchDelegate[T] func, System.Boolean bGameServer) [0x00000] in <00000000000000000000000000000000>:0
    at Steamworks.Callback`1[T].Create (Steamworks.Callback`1+DispatchDelegate[T] func) [0x00000] in <00000000000000000000000000000000>:0
    at IAPManager.Start () [0x00000] in <00000000000000000000000000000000>:0

    (Filename: currently not available on il2cpp Line: -1)

    Uploading Crash Report
    InvalidOperationException: Handle is not pinned.
    at System.Runtime.CompilerServices.FixedBufferAttribute..ctor (System.Type elementType, System.Int32 length) [0x00000] in <00000000000000000000000000000000>:0
    at Steamworks.Callback`1[T].Unregister () [0x00000] in <00000000000000000000000000000000>:0
    at Steamworks.Callback`1[T].Dispose () [0x00000] in <00000000000000000000000000000000>:0
    at Steamworks.Callback`1[T].Finalize () [0x00000] in <00000000000000000000000000000000>:0
    UnityEngine.Logger:LogException(Exception, Object)
    UnityEngine.Debug:LogException(Exception)
    System.Reflection.AddEventAdapter:Invoke(Object, Delegate)

    (Filename: currently not available on il2cpp Line: -1)
     
  10. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,680
    Right, so how you added [MonoPInvokeCallback] attribute on OnMicroTxnAuthorizationResponse on your first post, you need to do the same for these three methods.
     
  11. CryptoGrounds

    CryptoGrounds

    Joined:
    May 23, 2017
    Posts:
    12
    Well doing that now causes: https://hatebin.com/psreopmqol on build. Maybe its unrelated? I am not sure.
    In all honesty, I am not really sure why this is a struggle to implement. There is absolutely 0 forums online where people are in the same position as me.
     
  12. CryptoGrounds

    CryptoGrounds

    Joined:
    May 23, 2017
    Posts:
    12
    Ok so I have done some more research and my system is still messed up. So I fixed it and now I am getting the Steam Purchase confirmation. However, my callback is still generating errors:

    Code (CSharp):
    1.  
    2. private void Start()
    3.     {
    4.         if (steam.steamEnabled)
    5.         {
    6.             //m_MicroTxnAuthorizationResponse = Callback<MicroTxnAuthorizationResponse_t>.Create(OnMicroTxnAuthorizationResponse);
    7.             m_steamInventoryResultReady_t = Callback<SteamInventoryResultReady_t>.Create(OnSteamInventoryResultReady);
    8.         }
    9.     }
    10.  
    11. [MonoPInvokeCallback(typeof(SteamInventoryResultReady_t))]
    12.     private void OnSteamInventoryResultReady(SteamInventoryResultReady_t result)
    13.     {
    14.         print(result.m_result);
    15.         CanPurchase = result.m_result == EResult.k_EResultOK;
    16.         if (CanPurchase) BuyIAPChoice(productID);
    17.         productID = "";
    18.     }

    Uploading Crash Report
    NotSupportedException: To marshal a managed method, please add an attribute named 'MonoPInvokeCallback' to the method definition. The method we're attempting to marshal is: Steamworks.Callback`1[[Steamworks.SteamInventoryResultReady_t, Assembly-CSharp-firstpass, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]]::OnRunCallResult
    at Steamworks.Callback`1[T].BuildCCallbackBase () [0x00000] in <00000000000000000000000000000000>:0
    at Steamworks.Callback`1[T]..ctor (Steamworks.Callback`1+DispatchDelegate[T] func, System.Boolean bGameServer) [0x00000] in <00000000000000000000000000000000>:0
    at Steamworks.Callback`1[T].Create (Steamworks.Callback`1+DispatchDelegate[T] func) [0x00000] in <00000000000000000000000000000000>:0
    at IAPManager.Start () [0x00000] in <00000000000000000000000000000000>:0


    Any idea?
     
  13. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,680
    Looks like OnRunCallResult doesn't have [MonoPInvokeCallback] attribute on it anymore? Did you remove it?
     
  14. CryptoGrounds

    CryptoGrounds

    Joined:
    May 23, 2017
    Posts:
    12
    Are you reffering to this:

    Code (CSharp):
    1. [MonoPInvokeCallbackAttribute(typeof(SteamInventoryResultReady_t))]
    2.     private static void OnSteamInventoryResultReady(SteamInventoryResultReady_t result)
    3.     {
    4.         print(result.m_result);
    5.         CanPurchase = result.m_result == EResult.k_EResultOK;
    6.         //if (CanPurchase) BuyIAPChoice(productID);
    7.         //productID = "";
    8.     }
    9.  
    10. ...
    11.  
    12. [MonoPInvokeCallbackAttribute(typeof(SteamAPICall_t))]
    13.       private static void OnRunCallResult(
    14. #if !STDCALL
    15.          IntPtr thisptr,
    16. #endif
    17.          IntPtr pvParam, bool bFailed, ulong hSteamAPICall_) {
    18.          SteamAPICall_t hSteamAPICall = (SteamAPICall_t)hSteamAPICall_;
    19.          if (hSteamAPICall == m_hAPICall) {
    20.             m_hAPICall = SteamAPICall_t.Invalid; // Caller unregisters for us
    21.  
    22.             try {
    23.                m_Func((T)Marshal.PtrToStructure(pvParam, typeof(T)), bFailed);
    24.             }
    25.             catch (Exception e) {
    26.                CallbackDispatcher.ExceptionHandler(e);
    27.             }
    28.          }
    29.       }
    30.  
    31.  
     
  15. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,680
    Is that this method? "Steamworks.Callback`1[[Steamworks.SteamInventoryResultReady_t, Assembly-CSharp-firstpass, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]]::OnRunCallResult".

    It's bizarre it's giving you "To marshal a managed method, please add an attribute named 'MonoPInvokeCallback' to the method definition." error if it's the right method.
     
  16. CryptoGrounds

    CryptoGrounds

    Joined:
    May 23, 2017
    Posts:
    12
    Well I am not sure if it's referring to "OnRunCallResult" or SteamInventoryResultReady because it has both.

    But the error state that it originates in IAPManager.Start()

    Code (CSharp):
    1. private void Start()
    2.     {
    3.         iap = SaveSystemIAP.SaveExists("IAP") ? SaveSystemIAP.LoadPlayer<IAPData>("IAP") : new IAPData();
    4.  
    5.         if (steam.steamEnabled)
    6.         {
    7.             m_steamInventoryResultReady_t = Callback<SteamInventoryResultReady_t>.Create(OnSteamInventoryResultReady);
    8.         }
    9.     }
    Could it be something with this?
     
  17. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,680
    OIt is referring to Steamworks.Callback<SteamInventoryResultReady_t>.OnRunCallResult. If that's the only OnRunCallResult method, it has that attribute and you're still getting that error it might be a bug in Unity. Could you report a bug on ti?
     
  18. ZachAttack9280

    ZachAttack9280

    Joined:
    Sep 12, 2015
    Posts:
    18
    Sure, where can I do this? Also I am on version 2019.3.0f6, should I try updating?
     
  19. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,680
  20. ZachAttack9280

    ZachAttack9280

    Joined:
    Sep 12, 2015
    Posts:
    18
    Doing that now, and thank you.
     
  21. ZachAttack9280

    ZachAttack9280

    Joined:
    Sep 12, 2015
    Posts:
    18
    Code (CSharp):
    1. private void BuildCCallbackBase() {
    2.             m_CallbackBaseVTable = new CCallbackBaseVTable() {
    3.                 m_RunCallResult = OnRunCallResult,
    4.                 m_RunCallback = OnRunCallback,
    5.                 m_GetCallbackSizeBytes = OnGetCallbackSizeBytes
    6.             };
    7.             m_pVTable = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(CCallbackBaseVTable)));
    8.             Marshal.StructureToPtr(m_CallbackBaseVTable, m_pVTable, false);
    9.  
    10.             m_CCallbackBase = new CCallbackBase() {
    11.                 m_vfptr = m_pVTable,
    12.                 m_nCallbackFlags = 0,
    13.                 m_iCallback = CallbackIdentities.GetCallbackIdentity(typeof(T))
    14.             };
    15.             m_pCCallbackBase = GCHandle.Alloc(m_CCallbackBase, GCHandleType.Pinned);
    16.         }
    this method is part of the error, do you think something could be done here?
     
  22. ZachAttack9280

    ZachAttack9280

    Joined:
    Sep 12, 2015
    Posts:
    18
    Ok I think I am starting to get places, I am now shifting the error from OnRunCallResult to OnGetCallbackSizeBytes
    So I think my changes are working but I just keep to keep doing it till it's gone? Not sure, will keep this updated.
     
  23. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,680
    Yeah looks about right! You should add that attribute on OnGetCallbackSizeBytes too.
     
  24. ZachAttack9280

    ZachAttack9280

    Joined:
    Sep 12, 2015
    Posts:
    18
    Code (CSharp):
    1. [MonoPInvokeCallback(typeof(CallResult<int>))]
    2.         private static int OnGetCallbackSizeBytes(
    3. #if !STDCALL
    4.             IntPtr thisptr
    5. #endif
    6.             ) {
    7.             return m_size;
    8.         }
    So I tried this, also I did it with [MonoPInvokeCallback(typeof(IntPtr ))] however i get the annoying il2cpp.exe did not run properly! error again D:

    deeper in this error mentions it, but I cannot read it:

    Creating library C:\Users\zacha\Desktop\GitHub\CryptoClickers-REPO\Library\il2cpp_cache\linkresult_9A929D9B11F247782728BDA35E2D34A0\GameAssembly.lib and object C:\Users\zacha\Desktop\GitHub\CryptoClickers-REPO\Library\il2cpp_cache\linkresult_9A929D9B11F247782728BDA35E2D34A0\GameAssembly.exp
    911BAAEFA6D4DD5696DDB51F2C7CCA01.obj : error LNK2019: unresolved external symbol Callback_1_OnGetCallbackSizeBytes_m284F7533BBF199C27A40F820326D2613EA403C4B_gshared_inline referenced in function "int __cdecl Callback_1_OnGetCallbackSizeBytes_m284F7533BBF199C27A40F820326D2613EA403C4B_inline(__int64,struct MethodInfo const *)" (?Callback_1_OnGetCallbackSizeBytes_m284F7533BBF199C27A40F820326D2613EA403C4B_inline@@YAH_JPEBUMethodInfo@@@Z)
    911BAAEFA6D4DD5696DDB51F2C7CCA01.obj : error LNK2019: unresolved external symbol Callback_1_OnGetCallbackSizeBytes_mB855B218155D9029D6A9CF4AA095FF27CC5F06D7_gshared_inline referenced in function "int __cdecl Callback_1_OnGetCallbackSizeBytes_mB855B218155D9029D6A9CF4AA095FF27CC5F06D7_inline(__int64,struct MethodInfo const *)" (?Callback_1_OnGetCallbackSizeBytes_mB855B218155D9029D6A9CF4AA095FF27CC5F06D7_inline@@YAH_JPEBUMethodInfo@@@Z)
    911BAAEFA6D4DD5696DDB51F2C7CCA01.obj : error LNK2019: unresolved external symbol Callback_1_OnGetCallbackSizeBytes_m4813E389A68BBD141368F8F9965A1834ABFCA0AC_gshared_inline referenced in function "int __cdecl Callback_1_OnGetCallbackSizeBytes_m4813E389A68BBD141368F8F9965A1834ABFCA0AC_inline(__int64,struct MethodInfo const *)" (?Callback_1_OnGetCallbackSizeBytes_m4813E389A68BBD141368F8F9965A1834ABFCA0AC_inline@@YAH_JPEBUMethodInfo@@@Z)
    C:\Users\zacha\Desktop\GitHub\CryptoClickers-REPO\Library\il2cpp_cache\linkresult_9A929D9B11F247782728BDA35E2D34A0\GameAssembly.dll : fatal error LNK1120: 3 unresolved externals

    at Unity.IL2CPP.Building.CppProgramBuilder.PostprocessObjectFiles(HashSet`1 objectFiles, CppToolChainContext toolChainContext)
    at Unity.IL2CPP.Building.CppProgramBuilder.Build(IBuildStatistics& statistics)
    at il2cpp.Program.DoRun(String[] args, List`1 foundAssemblies)
    at il2cpp.Program.Run(String[] args, Boolean setInvariantCulture)
    at il2cpp.Program.Main(String[] args)
    stderr:

    Unhandled Exception: Unity.IL2CPP.Building.BuilderFailedException: C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.16.27023\bin\HostX64\x64\link.exe /out:"C:\Users\zacha\Desktop\GitHub\CryptoClickers-REPO\Library\il2cpp_cache\linkresult_9A929D9B11F247782728BDA35E2D34A0\GameAssembly.dll" /DEBUG /INCREMENTAL:NO /LARGEADDRESSAWARE /NXCOMPAT /DYNAMICBASE /NOLOGO /TLBID:1 /OPT:REF /OPT:ICF /HIGHENTROPYVA /DLL /IGNORE:4104 /NODEFAULTLIB:uuid.lib "kernel32.lib" "user32.lib" "advapi32.lib" "ole32.lib" "oleaut32.lib" "Shell32.lib" "Crypt32.lib" "psapi.lib" "version.lib" "MsWSock.lib" "ws2_32.lib" "Iphlpapi.lib" "Dbghelp.lib" /LIBPATH:"C:\Program Files (x86)\Windows Kits\10\Lib\10.0.16299.0\um\x64" /LIBPATH:"C:\Program Files (x86)\Windows Kits\10\Lib\10.0.16299.0\ucrt\x64" /LIBPATH:"C:\Program Files (x86)\Windows Kits\NETFXSDK\4.6.1\lib\um\x64" /LIBPATH:"C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.16.27023\lib\x64" /SUBSYSTEM:WINDOWS @"C:\Users\zacha\AppData\Local\Temp\tmp433F.tmp"

    Creating library C:\Users\zacha\Desktop\GitHub\CryptoClickers-REPO\Library\il2cpp_cache\linkresult_9A929D9B11F247782728BDA35E2D34A0\GameAssembly.lib and object C:\Users\zacha\Desktop\GitHub\CryptoClickers-REPO\Library\il2cpp_cache\linkresult_9A929D9B11F247782728BDA35E2D34A0\GameAssembly.exp
    911BAAEFA6D4DD5696DDB51F2C7CCA01.obj : error LNK2019: unresolved external symbol Callback_1_OnGetCallbackSizeBytes_m284F7533BBF199C27A40F820326D2613EA403C4B_gshared_inline referenced in function "int __cdecl Callback_1_OnGetCallbackSizeBytes_m284F7533BBF199C27A40F820326D2613EA403C4B_inline(__int64,struct MethodInfo const *)" (?Callback_1_OnGetCallbackSizeBytes_m284F7533BBF199C27A40F820326D2613EA403C4B_inline@@YAH_JPEBUMethodInfo@@@Z)
    911BAAEFA6D4DD5696DDB51F2C7CCA01.obj : error LNK2019: unresolved external symbol Callback_1_OnGetCallbackSizeBytes_mB855B218155D9029D6A9CF4AA095FF27CC5F06D7_gshared_inline referenced in function "int __cdecl Callback_1_OnGetCallbackSizeBytes_mB855B218155D9029D6A9CF4AA095FF27CC5F06D7_inline(__int64,struct MethodInfo const *)" (?Callback_1_OnGetCallbackSizeBytes_mB855B218155D9029D6A9CF4AA095FF27CC5F06D7_inline@@YAH_JPEBUMethodInfo@@@Z)
    911BAAEFA6D4DD5696DDB51F2C7CCA01.obj : error LNK2019: unresolved external symbol Callback_1_OnGetCallbackSizeBytes_m4813E389A68BBD141368F8F9965A1834ABFCA0AC_gshared_inline referenced in function "int __cdecl Callback_1_OnGetCallbackSizeBytes_m4813E389A68BBD141368F8F9965A1834ABFCA0AC_inline(__int64,struct MethodInfo const *)" (?Callback_1_OnGetCallbackSizeBytes_m4813E389A68BBD141368F8F9965A1834ABFCA0AC_inline@@YAH_JPEBUMethodInfo@@@Z)
    C:\Users\zacha\Desktop\GitHub\CryptoClickers-REPO\Library\il2cpp_cache\linkresult_9A929D9B11F247782728BDA35E2D34A0\GameAssembly.dll : fatal error LNK1120: 3 unresolved externals
     
  25. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,680
    Damn, I wonder if it's because these methods are part of a generic class. An error that you posted above is definitely a bug in Unity: we should not fail like that. If you could, please report a bug.

    In the meantime, can you try moving these methods to be in a non-generic class?
     
  26. ZachAttack9280

    ZachAttack9280

    Joined:
    Sep 12, 2015
    Posts:
    18
    Yes I will report, but how do I move these methods to a non generic class? Not even sure what a "generic" class is haha.
     
  27. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,680
  28. ZachAttack9280

    ZachAttack9280

    Joined:
    Sep 12, 2015
    Posts:
    18
    I have this however I am still getting that same build error and it looks like it related to OnGetCallbackSizeBytes again D:

    Code (CSharp):
    1. public static class CallResult
    2.     {
    3.         private delegate void APIDispatchDelegate(object param, bool bIOFailure);
    4.         private static event APIDispatchDelegate m_Func;
    5.        
    6.         private static SteamAPICall_t m_hAPICall = SteamAPICall_t.Invalid;
    7.         public static SteamAPICall_t Handle => m_hAPICall;
    8.        
    9.         private static readonly int m_size = Marshal.SizeOf(typeof(object));
    10.        
    11.         [MonoPInvokeCallback(typeof(CCallbackBaseVTable.RunCBDel))]
    12.         public static void OnRunCallback(
    13. #if !STDCALL
    14.             IntPtr thisptr,
    15. #endif
    16.             IntPtr pvParam) {
    17.             m_hAPICall = SteamAPICall_t.Invalid; // Caller unregisters for us
    18.  
    19.             try {
    20.                 m_Func(Marshal.PtrToStructure(pvParam, typeof(object)), false);
    21.             }
    22.             catch (Exception e) {
    23.                 CallbackDispatcher.ExceptionHandler(e);
    24.             }
    25.         }
    26.        
    27.         [MonoPInvokeCallback(typeof(CCallbackBaseVTable.RunCRDel))]
    28.         public static void OnRunCallResult(
    29. #if !STDCALL
    30.             IntPtr thisptr,
    31. #endif
    32.             IntPtr pvParam, bool bFailed, ulong hSteamAPICall_) {
    33.             var hSteamAPICall = (SteamAPICall_t)hSteamAPICall_;
    34.             if (hSteamAPICall != m_hAPICall) return;
    35.             m_hAPICall = SteamAPICall_t.Invalid; // Caller unregisters for us
    36.  
    37.             try {
    38.                 m_Func((object)Marshal.PtrToStructure(pvParam, typeof(object)), bFailed);
    39.             }
    40.             catch (Exception e) {
    41.                 CallbackDispatcher.ExceptionHandler(e);
    42.             }
    43.         }
    44.  
    45.         [MonoPInvokeCallback(typeof(CCallbackBaseVTable.GetCallbackSizeBytesDel))]
    46.         public static int OnGetCallbackSizeBytes(
    47. #if !STDCALL
    48.             IntPtr thisptr
    49. #endif
    50.         ) {
    51.             return m_size;
    52.         }
    53.        
    54.     }
    55.  
     
  29. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,680
    Can you show the error?
     
  30. ZachAttack9280

    ZachAttack9280

    Joined:
    Sep 12, 2015
    Posts:
    18
    Ahhhh i got those errors to fade away! but i got new ones D:


    ArgumentException: Type 'System.Object' cannot be marshaled as an unmanaged structure; no meaningful size or offset can be computed.
    at Steamworks.Callback..cctor () [0x00000] in <00000000000000000000000000000000>:0
    at Steamworks.Callback.OnRunCallback (System.IntPtr thisptr, System.IntPtr pvParam) [0x00000] in <00000000000000000000000000000000>:0
    at Steamworks.NativeMethods.SteamAPI_RunCallbacks () [0x00000] in <00000000000000000000000000000000>:0
    Rethrow as TypeInitializationException: The type initializer for 'Steamworks.Callback' threw an exception.
    at Steamworks.Callback.OnRunCallback (System.IntPtr thisptr, System.IntPtr pvParam) [0x00000] in <00000000000000000000000000000000>:0
    at Steamworks.NativeMethods.SteamAPI_RunCallbacks () [0x00000] in <00000000000000000000000000000000>:0
    UnityEngine.Logger:LogException(Exception, Object)
    UnityEngine.Debug:LogException(Exception)
    Steamworks.Callback:OnRunCallback(IntPtr, IntPtr)
    Steamworks.NativeMethods:SteamAPI_RunCallbacks()


    Looks like it appears here:
    Code (CSharp):
    1.  
    2. public static void OnRunCallback(#if !STDCALL IntPtr thisptr, #endif IntPtr pvParam) {
    3.             try {
    4.                 m_Func(Marshal.PtrToStructure(pvParam, typeof(object)));  <--- occurs here
    5.             }
    6.             catch (Exception e) {
    7.                 CallbackDispatcher.ExceptionHandler(e);
    8.             }
    9.         }
     
    Last edited: Jul 23, 2020
  31. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,680
    Indeed, that is unsupported. That type should be a concrete object type.
     
  32. ZachAttack9280

    ZachAttack9280

    Joined:
    Sep 12, 2015
    Posts:
    18
    I am not really sure what to replace it with...
    Since originally it was:
    m_Func((T)Marshal.PtrToStructure(pvParam, typeof(T)));
     
  33. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,680
    Well, you originally instantiated that Callback class with MicroTxnAuthorizationResponse_t argument:

    Code (csharp):
    1. m_MicroTxnAuthorizationResponse = Callback<MicroTxnAuthorizationResponse_t>.Create(OnMicroTxnAuthorizationResponse);
    So perhaps that?
     
  34. ZachAttack9280

    ZachAttack9280

    Joined:
    Sep 12, 2015
    Posts:
    18
    I replaced all "object" with that and now I am getting this:

    NullReferenceException: Object reference not set to an instance of an object.
    at Steamworks.Callback.OnRunCallback (System.IntPtr thisptr, System.IntPtr pvParam) [0x00000] in <00000000000000000000000000000000>:0
    at Steamworks.SteamAPI.RunCallbacks () [0x00000] in <00000000000000000000000000000000>:0
    UnityEngine.Logger:LogException(Exception, Object)
    UnityEngine.Debug:LogException(Exception)
    Steamworks.Callback:OnRunCallback(IntPtr, IntPtr)
    Steamworks.SteamAPI:RunCallbacks()


    MicroTxnAuthorizationResponse_t is a struct, not sure if that changes anything.
     
    Last edited: Jul 23, 2020
  35. ZachAttack9280

    ZachAttack9280

    Joined:
    Sep 12, 2015
    Posts:
    18
    Think I found something online, looks like this one guy is doing it this way for example:
    Code (CSharp):
    1. [MonoPInvokeCallback(typeof(CCallbackBaseVTable.RunCBDel))]
    2.         public static void OnRunCallback(
    3. #if !STDCALL
    4.             IntPtr thisptr,
    5. #endif
    6.             IntPtr pvParam) {
    7.             try
    8.             {
    9.                 var result =
    10.                     (MicroTxnAuthorizationResponse_t) Marshal.PtrToStructure(pvParam,
    11.                         typeof(MicroTxnAuthorizationResponse_t));
    12.                 _callbackAction(result);
    13.             }
    14.             catch (Exception e) {
    15.                 CallbackDispatcher.ExceptionHandler(e);
    16.             }
    17.         }
    Going to give it a shot
     
  36. ZachAttack9280

    ZachAttack9280

    Joined:
    Sep 12, 2015
    Posts:
    18
    Got it working!!!
    Instructions:
    0. Make sure you have the latest steamworks.github.io steamworks sdk
    1. Create a new script, idk something like SteamCallbacksIL2CPP
    2. https://gist.githubusercontent.com/...da4937b9d95ff6e251f131da0ba/SteamCallbacks.cs paste all of this in your new script
    3. You will probably get some errors like NativeMethods isn't accesible, just make the class public instead of internal
    4. You will always get some errors like GetVideoURLResult_t doesn't exist in Steamworks, delete any classes in that situation
    Bam done, more info here though: https://github.com/rlabrecque/Steamworks.NET/issues/227

    Code (CSharp):
    1.  
    2. public void OnEnable()
    3.     {
    4. #if UNITY_STANDALONE
    5.         if (steam.steamEnabled) SteamCallbacks.SteamInventoryResultReady_t.RegisterCallback(OnSteamInventoryResultReady);
    6.         #endif
    7.     }
    8. [MonoPInvokeCallbackAttribute(typeof(SteamInventoryResultReady_t))]
    9. private static void OnSteamInventoryResultReady(SteamInventoryResultReady_t result)
    10. {
    11.     print(result.m_result);
    12.     CanPurchase = result.m_result == EResult.k_EResultOK;
    13.     //if (CanPurchase) BuyIAPChoice(productID);
    14.     //productID = "";
    15. }
    16.  
    Thank you for helping me along the way, was a very tedious process but definitely learned lots haha. I extremely appreciate it as this has been stressing me out a lot :D
     
    Last edited: Jul 23, 2020
    Volchok and Brewmaster like this.
  37. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,680
    I'm glad you sorted it out! We'll still be waiting for that bug report you promised :).
     
  38. ZachAttack9280

    ZachAttack9280

    Joined:
    Sep 12, 2015
    Posts:
    18
    I submitted yesterday, hoping it got all the right info: case 1265164.
     
  39. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,680
    Yep, that will do.
     
  40. Volchok

    Volchok

    Joined:
    Jul 26, 2017
    Posts:
    127
    Great! It works! But not for all solutions. Can you advise how to register a callback for SetWarningMessageHook?

    Code (CSharp):
    1. void OnEnable() {
    2.      m_SteamAPIWarningMessageHook = new  SteamAPIWarningMessageHook_t(SteamAPIDebugTextHook);
    3.      SteamClient.SetWarningMessageHook(m_SteamAPIWarningMessageHook);
    4. }
    5.  
    6. protected SteamAPIWarningMessageHook_t m_SteamAPIWarningMessageHook;
    7. protected static void SteamAPIDebugTextHook(int nSeverity, System.Text.StringBuilder pchDebugText) {
    8.      Debug.LogWarning(pchDebugText);
    9. }
    I tried it myself, but it didn't work out. In IL2CPP in the build, this code always generates such an error:

    Code (CSharp):
    1. NotSupportedException: To marshal a managed method, please add an attribute named 'MonoPInvokeCallback' to the method definition. The method we're attempting to marshal is: SteamManager::SteamAPIDebugTextHook
    2.  at Steamworks.NativeMethods.ISteamClient_SetWarningMessageHook (System.IntPtr instancePtr, Steamworks.SteamAPIWarningMessageHook_t pFunction) [0x00000] in <00000000000000000000000000000000>:0
    3.  at SteamManager.OnEnable () [0x00000] in <00000000000000000000000000000000>:0
     
  41. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,680
    Add [MonoPInvokeCallback] attribute on SteamAPIDebugTextHook like the error says.
     
    Volchok likes this.
  42. Volchok

    Volchok

    Joined:
    Jul 26, 2017
    Posts:
    127
    Thanks, I'll try. :)
     
  43. Haapavuo

    Haapavuo

    Joined:
    Sep 19, 2015
    Posts:
    97