Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #define _CRT_SECURE_NO_WARNINGS
- #include <windows.h>
- #include <stdio.h>
- class CSharpScriptFire{
- public:
- CSharpScriptFire(){
- ZeroMemory(this, sizeof(CSharpScriptFire));
- InitializeCriticalSection(&this->CS_Exhange);
- }
- ~CSharpScriptFire(){
- if (CriticalExhange)
- delete[]CriticalExhange;
- DeleteCriticalSection(&this->CS_Exhange);
- ZeroMemory(this, sizeof(CSharpScriptFire));
- }
- //Check if the exhange has any data and if so copies it to request
- //If this returns true you MUST run MainLoop_SetReturn
- //If it returns false the mainthread should continue as there was no request
- bool MainLoop_GetRequest( char * request );
- //Set the data to be returned to the caller
- bool MainLoop_SetReturn( const char * CSharpRet );
- //Call the mainloop from C#
- //Results are copied back into request
- bool CSharpRequest(char * request);
- private:
- CRITICAL_SECTION CS_Exhange;
- char * CriticalExhange;
- int Stage;
- };
- bool CSharpScriptFire::MainLoop_GetRequest(char * request){
- //Enter critical section
- EnterCriticalSection(&this->CS_Exhange);
- if (Stage == 1 && CriticalExhange){
- strcpy(request, CriticalExhange);
- delete[]CriticalExhange;
- CriticalExhange = NULL;
- //You have to call MainLoop_SetReturn yourself from here on out
- return true;
- }
- //Nothing, leave the critical section
- LeaveCriticalSection(&this->CS_Exhange);
- return false;
- }
- bool CSharpScriptFire::MainLoop_SetReturn(const char * CSharpRet){
- //If this runs we're still in the critical section so we don't need to enter it again
- CriticalExhange = new char[strlen(CSharpRet) + 1];
- if (!CriticalExhange)return false;
- strcpy(CriticalExhange, CSharpRet);
- Stage = 2;
- LeaveCriticalSection(&this->CS_Exhange);
- }
- bool CSharpScriptFire::CSharpRequest(char * request){
- EnterCriticalSection(&this->CS_Exhange);
- if (CriticalExhange)
- delete[]CriticalExhange;
- //Set the exhange data and flag stage to 1
- CriticalExhange = new char[strlen(request) + 1];
- if (!CriticalExhange)return false;
- strcpy(CriticalExhange, request);
- Stage = 1;
- LeaveCriticalSection(&this->CS_Exhange);
- //wait
- while (true){
- EnterCriticalSection(&this->CS_Exhange);
- if (Stage == 2){
- break; //We are still in the critical section here
- }
- else if (Stage <= 0 || Stage > 2){
- LeaveCriticalSection(&this->CS_Exhange);
- return false;
- }
- LeaveCriticalSection(&this->CS_Exhange);
- }
- if (!CriticalExhange)
- return false;
- //Get the exhange data
- strcpy(request, CriticalExhange);
- //Cleanup
- delete[]CriticalExhange;
- CriticalExhange = NULL;
- //Return true and leave the critical section
- LeaveCriticalSection(&this->CS_Exhange);
- return true;
- }
- //NWN Stuff down here
- //The exhange class has to be global or in a class accessible for your wrapper
- CSharpScriptFire * CSSF;
- //This is the c++ wrapper
- void CSharpRunScript(const char * str){
- char Buffer[512];
- if (!CSSF)
- return;
- strcpy(Buffer,str);
- if (CSSF->CSharpRequest(Buffer)){
- printf("C#: %s\n", Buffer);
- }
- else{
- printf("C#: %s\n", "Got nothing from C++");
- }
- }
- //This is our test function its really the csharp thread
- DWORD WINAPI Testy(LPVOID lpParam){
- char Buffer[512];
- while (true){
- //This could just aswell be a C# event
- //For this test its user input using scanf
- printf("Your text: ");
- scanf("%s", Buffer);
- //Call the wrapper
- CSharpRunScript(Buffer);
- //die is the singal to die
- if (strcmp(Buffer, "die") == 0)
- break;
- }
- return 0;
- }
- void main(){
- DWORD TestyThread;
- HANDLE TestThread = CreateThread(NULL, 0, Testy, NULL, CREATE_SUSPENDED, &TestyThread);
- CSSF = new CSharpScriptFire;
- char Buffer[512];
- //Start the C# thread here for the test
- ResumeThread(TestThread);
- while (true){
- //Check if we got something
- if (CSSF->MainLoop_GetRequest(Buffer)){
- printf("C++: %s\n", Buffer);
- //If the message is die then kill the mainthread after 5 sec
- if (strcmp(Buffer, "die") == 0){
- strcpy(Buffer,"I'll now sleep and die in 5 seconds");
- CSSF->MainLoop_SetReturn(Buffer);
- Sleep(5000);
- break;
- }
- //We sleep a sec here, you'll notice that the C# thread is actually waiting
- Sleep(1000);
- //Give C# some data
- sprintf(Buffer,"The text was %u chars long",strlen(Buffer));
- //We have to return something to the threat which is waiting
- CSSF->MainLoop_SetReturn(Buffer);
- }
- //Here you should call the callback to the mainloop proc since
- //in nwserver this isnt an actual loop
- }
- //Clean up our test, CSSF shoudlnt be deleted until C# is dead
- CloseHandle(TestThread );
- delete CSSF;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement