C/C++ Project Problem or Issue Summary
1.Explicit Key Word
2.Volatile Key Word
3.How to Convert C Pointer to Ref Implement Auto Release
4.C++ Exception
5.How to Implements delegate in C++
6.How to Deal with C++ CallBack in C#
6.1. C# Delegate Set to Native C++ Code for None UWP
- C# warp for C++ DLL
internal class VoiceCoreWrapper
{
[DllImport("VoiceCore.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public static extern bool SetSpeechCallback(TTSCallback callback);
}
- C# Delegate Define
public delegate void TTSCallback(RecognizeEvent evt, string text);
- Set C# CallBack to Native Dll
public bool SetCallback(TTSCallback callback)
{
if (_selectEngine == SpeechEngine.VSI)
{
return VoiceCoreWrapper.SetSpeechCallback(callback);
}
return true;
}
- Native Code CallBack Define
typedef void(CALLBACK *TTSCallback)(int, char*);
- Delegate implement in C#
VoiceRecognizeController.Instance.SetSpeechCallback(delegate (RecognizeEvent a, string t)
{
if (a == RecognizeEvent.speech_final)
{
if (isWakeupWordRepeat)
{
VoiceRecognizeController.Instance.RecognizeStart("click", 15000);
}
else
{
VoiceServiceController.Instance.OnVoiceTaskEndEvent(TaskEndEventType.WakeupAgain);
}
}
else if (a == RecognizeEvent.speech_cancel)
{
//
}
});
6.2. C# Delegate Set to C++ (C++/CX or C++/WINRT)
- C++/CX Declaration and Define
namespace VSISDK_RT
{
public delegate void VSICALLBACK(int message, VSI_UNIVERSAL_TYPE hIns, VSI_UNIVERSAL_TYPE hUserData, VSI_UNIVERSAL_TYPE fstParam, VSI_UNIVERSAL_TYPE sndParam, VSI_UNIVERSAL_TYPE thdParam);
public ref class VSISDK sealed
{
public:
VSISDK();
event VSICALLBACK^ delegateCallBack;
......
void CXCallBack(int message, VSI_UNIVERSAL_TYPE hIns, VSI_UNIVERSAL_TYPE hUserData, VSI_UNIVERSAL_TYPE fstParam, VSI_UNIVERSAL_TYPE sndParam, VSI_UNIVERSAL_TYPE thdParam);
}
}
- The Implement in Native C++ Code
VSISDK^ pThis;
VSISDK::VSISDK()
{
pThis = this;
}
void VSICB(int message, VSI_UNIVERSAL_TYPE hIns, VSI_UNIVERSAL_TYPE hUserData, VSI_UNIVERSAL_TYPE fstParam, VSI_UNIVERSAL_TYPE sndParam, VSI_UNIVERSAL_TYPE thdParam)
{
pThis->CXCallBack(message, hIns, hUserData, fstParam, sndParam, thdParam);
}
void VSISDK_RT::VSISDK::CXCallBack(int message, VSI_UNIVERSAL_TYPE hIns, VSI_UNIVERSAL_TYPE hUserData, VSI_UNIVERSAL_TYPE fstParam, VSI_UNIVERSAL_TYPE sndParam, VSI_UNIVERSAL_TYPE thdParam)
{
pThis->delegateCallBack(message, hIns, hUserData, fstParam, sndParam, thdParam);
}
The function VSICB is the C style function,In the Native Code it used as a CallBack function,it May Called by another function or another thread from Native Code.
4. The Implement in C#
namespace CXTestApp
{
public delegate void VSICALLBACK(int message, UInt64 hIns, UInt64 hUserData, UInt64 fstParam, UInt64 sndParam, UInt64 thdParam);
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
VSISDK rt = new VSISDK();
rt.delegateCallBack += new VSISDK_RT.VSICALLBACK(VSICallBack);
rt.VSISetOpt(0, "sss", "ssss");
}
void VSICallBack(int message, UInt64 hIns, UInt64 hUserData, UInt64 fstParam, UInt64 sndParam, UInt64 thdParam)
{
int i = 0;
i = i + 10;
}
}
}
C# Muti-Thread In Universal Windows Platform
Task-based asynchronous programming detail reference:
Task task = new Task(() =>
{
string path = @"E:\git-code\CUISDKrt\bin\x64\Debug\AppX\music5.wav";
FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read);
BinaryReader br = new BinaryReader(fs);
VSISDKrt.VSISetOpt(handle, CONS_DEFINE.VSI_OPTION_POSTVOICE, "1");
VSISDKrt.VSIPost(handle, CONS_DEFINE.L_MSG_REQUEST_STARTREC, 0, 0);
while (true)
{
byte[] byteArray = br.ReadBytes(3200);
IntPtr pBuffer = Marshal.AllocHGlobal(3200);
Marshal.Copy(byteArray, 0, pBuffer, byteArray.Length);
VSISDKrt.VSIPost(handle,
CONS_DEFINE.L_MSG_ACTION_POSTDATA,
(UInt64)byteArray.Length,
(UInt64)pBuffer.ToInt64());
Marshal.FreeHGlobal(pBuffer);
if (byteArray.Length < 3200)
{
VSISDKrt.VSIPost(handle, CONS_DEFINE.L_MSG_REQUEST_STOPREC, 0, 0);
System.Diagnostics.Debug.WriteLine("The Post Voice Task Have Done.");
break;
}
Task.Delay(100).Wait();
}
});
task.Start();