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