samedi 27 juin 2015

I got System.AccessViolationException in SL5 pinvoke call

I got System.AccessViolationException in SL5 pinvoke call.

I have SL5 application and c++ unmanaged dll and unmanaged dll callback the SL application by using AllowReversePInvokeCalls. Specially native dll is cosisted of QT dlls. ( I think that this is not matter at this problem. ) Very strangely the callback call works well after I just write code but after few hours gone it do not work any more.

My codes follows :

SL5 :

public static class PosBridgeFunctions
{
    // This is init method.
    // It register callback function from unmanaged dll to SL5 application.
    // And the dll path is relative to xap path, so I use win32's LoadLibrary, GetProcAddress.
    public static void Init()
    {
        var dllPath = KosUtils.GetRootDir() + @"\posBridge.dll";
        Log.d("dllPath : " + dllPath);
        var hDll = Win32SdkFunctions.LoadLibrary(dllPath);

        {
            var pFunc = Win32SdkFunctions.GetProcAddress(hDll, @"RegisterLogCallback");
            RegisterLogCallbackFunc = (RegisterLogCallbackDelegate)Marshal.GetDelegateForFunctionPointer(pFunc, typeof(RegisterLogCallbackDelegate));
        }

        {
            var pFunc = Win32SdkFunctions.GetProcAddress(hDll, @"RequestPrint");
            RequestPrintFunc = (RequestPrintDelegate)Marshal.GetDelegateForFunctionPointer(pFunc, typeof(RequestPrintDelegate));
            Log.d("RequestPrintFunc == null : " + (RequestPrintFunc == null));
        }

        RegisterLogCallbackFunc(OnLogCallback);
    }

    // This is callback method.
    [AllowReversePInvokeCalls]
    private static void OnLogCallback([MarshalAs(UnmanagedType.LPStr)]string message)
    {
        Log.d(message);
    }

    // This is callback's delegate type.
    public delegate void OnCallbackDelegate([MarshalAs(UnmanagedType.LPStr)]string message);

    // This is register function's delegate type.
    public delegate void RegisterLogCallbackDelegate(OnCallbackDelegate callback);

    // This is register function's delegate object.
    public static RegisterLogCallbackDelegate RegisterLogCallbackFunc;




    // This is native forward call delegate type.
    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
    private delegate void RequestPrintDelegate(
        [MarshalAs(UnmanagedType.LPWStr)]string orderJsonStr);

    // This is native forward call delegate object.
    private static RequestPrintDelegate RequestPrintFunc;

    // This is native forward call wrapper.
    public static void RequestPrint(PbIOrderReceiptInfo orderReceiptInfo)
    {
        try
        {
            var jsonStr = JsonConvert.SerializeObject(orderReceiptInfo, Formatting.Indented);
            RequestPrintFunc(jsonStr);
        }
        catch (Exception ex)
        {
            Log.d("ex : " + ex);
        }
    }
}

And unmanaged c++ dll header file :

#ifdef POSBRIDGE_LIB
# define POSBRIDGE_EXPORT Q_DECL_EXPORT
#else
# define POSBRIDGE_EXPORT Q_DECL_IMPORT
#endif


typedef void(__stdcall *OnCallbackDelegate) (char*);

extern "C" POSBRIDGE_EXPORT void RegisterLogCallback(OnCallbackDelegate callback);

extern "C" POSBRIDGE_EXPORT OnCallbackDelegate gpOnCallbackDelegate;

extern "C" POSBRIDGE_EXPORT void CallLogCallback(char* szMessage);

extern "C" POSBRIDGE_EXPORT void RequestPrint(wchar_t* pwOrderJsonStr);

And unmanaged c++ dll source file :

extern "C" POSBRIDGE_EXPORT OnCallbackDelegate gpOnCallbackDelegate = NULL;

extern "C" POSBRIDGE_EXPORT void RegisterLogCallback(OnCallbackDelegate callback)
{
    gpOnCallbackDelegate = callback;
}

extern "C" POSBRIDGE_EXPORT void CallLogCallback(char* szMessage)
{
    if (gpOnCallbackDelegate == NULL)
    {
        qDebug() << szMessage;
    }
    else
    {
        int length = strlen(szMessage) + 1;
        char* szMessageReturn = (char*)::CoTaskMemAlloc(length);
        strncpy(szMessageReturn, szMessage, length);
        gpOnCallbackDelegate(szMessageReturn);
    }
}

extern "C" POSBRIDGE_EXPORT void RequestPrint(wchar_t* pwOrderJsonStr)
{
    // This callback function make exception.
    CallLogCallback("POSBRIDGE_EXPORT void RequestPrint");

    // ... some logic here ...
}

Aucun commentaire:

Enregistrer un commentaire