Search Unity

  1. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Question Cpp plugin and unsafe code problem

Discussion in 'Scripting' started by sergienko88, Oct 7, 2023.

  1. sergienko88

    sergienko88

    Joined:
    Jul 22, 2013
    Posts:
    22
    Hello.I want to recieve message from cpp dll.
    So...
    1. Need delegate [see C# code: DebugLogCallback(string message)]
    2. Send it to cpp side [see C# code: Start-> InitializeDebug(DebugLogCallback callback)]
    3. Then call [see Cpp code: SendLog(std::string message)] All ok.
    But how about unsafe code via delegate pointer[InitializeDelegatePointerString(delegate*<string, void> callback)]?
    1. Send ptr to cpp side[see C# code: Start-> InitializeDelegatePointerString(&DelegatePointerCallback)]
    2. Call [see Cpp code: InitializeDelegatePointerString(DelegatePointer delegatePointer)] .
      Aaaand we have a problem [see C# code: DelegatePointerCallback(string message))
    On call DelegatePointerCallback from cpp side there is strange data in parameter, but length of this string is correct.
    In cpp side -> Hello
    output on C# side-> (item as byte) 0,0,15,0,0

    Also I try send char or int in params (delegate*<string,int/char, void> callback) - all ok(except string param).
    What im doing wrong?

    C# code
    Code (CSharp):
    1. public class DllTest : MonoBehaviour
    2. {
    3.     public const string dllName = "ProjectCppDll";
    4.  
    5.     #region Cpp Lib Func Prototypes
    6.  
    7.     [DllImport(dllName)]
    8.     public extern static void InitializeDebug(DebugLogCallback callback);
    9.  
    10.     [DllImport(dllName)]
    11.     public unsafe extern static void InitializeDelegatePointerString(delegate*<string, void> callback);
    12.  
    13.     [DllImport(dllName)]
    14.     public extern static void Clear();
    15.  
    16.     #endregion
    17.  
    18.     #region Cpp Lib Callbacks
    19.  
    20.     private static void DelegateDebugLogCallback(string message)
    21.     {
    22.         Debug.Log(message);
    23.     }
    24.  
    25.     private static void DelegatePointerCallback(string message)
    26.     {
    27.         Debug.Log($"{nameof(DelegatePointerCallback)}; Message length: {message.Length}");
    28.         for (int i = 0; i < message.Length; i++)
    29.         {
    30.             Debug.Log($"[{i}] {(byte)message[i]} : {message[i]}"); //sended Hello, result 0,0,15,0,0
    31.         }
    32.     }
    33.  
    34.     #endregion
    35.  
    36.     public delegate void DebugLogCallback(string message);
    37.  
    38.     private void Start()
    39.     {
    40.         try
    41.         {
    42.             InitializeDebug(DelegateDebugLogCallback);
    43.  
    44.             unsafe
    45.             {
    46.                 InitializeDelegatePointerString(&DelegatePointerCallback);
    47.             }
    48.         }
    49.         catch(Exception e)
    50.         {
    51.             Debug.LogError($"ERROR: {e.Message}\n{e.StackTrace}");
    52.         }
    53.     }
    54.  
    55.     private void OnDestroy()
    56.     {
    57.         try
    58.         {
    59.             Clear();
    60.             Debug.Log($"{nameof(Clear)}");
    61.         }
    62.         catch (Exception e)
    63.         {
    64.             Debug.LogError($"{nameof(OnDestroy)} ERROR: {e.Message}");
    65.         }
    66.     }
    67. }
    CPP PLUGIN CODE
    Header
    Code (C++):
    1. #pragma once
    2. #ifdef MYLIB_EXPORTS
    3. #define MYLIB_API __declspec(dllexport)
    4. #else
    5. #define MYLIB_API __declspec(dllimport)
    6. #endif
    7.  
    8. extern "C"
    9. {
    10.     typedef void(*DebugPointer)(const char* message);
    11.     typedef void(*DelegatePointer)(const char* message);
    12.  
    13.     MYLIB_API void InitializeDebug(DebugPointer debugPointer);
    14.     MYLIB_API void InitializeDelegatePointerString(DelegatePointer delegatePtr);
    15.  
    16.     MYLIB_API void Clear();
    17. }
    18.  
    19. void SendLog(std::string s);
    Source code
    Code (C++):
    1. #include "pch.h"
    2. #include <iostream>
    3. #include "MyLibHeader.h"
    4.  
    5.  
    6. static DebugPointer s_debugPtr = nullptr;
    7. static DelegatePointer s_delegatePtr = nullptr;
    8.  
    9. void InitializeDebug(DebugPointer debugPointer)
    10. {
    11.     s_debugPtr = debugPointer;
    12. }
    13.  
    14. void InitializeDelegatePointerString(DelegatePointer delegatePointer)
    15. {
    16.     s_delegatePtr = delegatePointer;
    17.     SendLog("Call InitializeDelegatePointerString");
    18.    //>> PROBLEM!
    19.     std::string message = "Hello";
    20.     const char* msg = message.c_str();
    21.  
    22.     (*s_delegatePtr)(msg);
    23.    //<<
    24.     SendLog(msg);
    25. }
    26.  
    27. void Clear()
    28. {
    29.     s_debugPtr = nullptr;
    30.     s_delegatePtr = nullptr;
    31. }
    32.  
    33. void SendLog(std::string message)
    34. {
    35.     message = "(C++ lib log): " + message;
    36.     const char* tempMessage = message.c_str();
    37.     if (s_debugPtr != nullptr)
    38.     {
    39.         s_debugPtr(tempMessage);
    40.     }
    41. }
     
    Last edited: Oct 7, 2023