⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 labview_test_controller.cpp

📁 ace开发环境 用来开发网络程序 其运用了设计模式、多平台、C++等多种知识
💻 CPP
📖 第 1 页 / 共 2 页
字号:
                             0,    // security                             CREATE_ALWAYS,                             FILE_ATTRIBUTE_NORMAL,                             0);          SetStdHandle (STD_OUTPUT_HANDLE, logf);          SetStdHandle (STD_ERROR_HANDLE, logf);        }    }  else    {      this->reply ("Unrecognized command\n");      return -1;    }  return 0;}intPeer::reply (const char *msg){  int len = (int)strlen (msg);    // size_t -> int  return send (this->handle_, msg, len, 0) > 0 ? 0 : -1;}Test::~Test (){  this->cleanup ();}intTest::run (void){  this->running_ = true;  this->status_ = (this->entry_) (this->argc_, this->argv_);  this->running_ = false;  // It's possible to cleanup() here; however, that would introduce a race  // with start() following beginthreadex(). So do all the cleanup on user  // action - either getting status, waiting, killing, or running another  // test. Or, terminating the connection.  return 0;}const char *Test::start (const char *name){  if (this->running_)    return "Already running\n";  const char *msg = 0;  // Reset test status to not inadvertantly report a previous test.  this->status_ = -1;  this->cleanup ();     // Resets cmdline_, argc_, argv_  // The command line is part-way through being tokenized by strtok(). It  // left off after the program name. Anything remaining are the command  // line arguments for the program. Pick off whatever is there, copy it  // to the cmdline_ array and fill in argc_/argv_ for the eventual run.  strcpy (this->name_, name);  this->argv_[0] = this->name_;  this->argc_ = 1;  size_t cmdchars = 0;  for (char *token = strtok (0, "\t \n\r");       token != 0 && (cmdchars + strlen (token) + 1) < CMDLINE_LEN;       token = strtok (0, "\t \n\r"))    {      // We have a new token and it will fit in cmdline_. Copy it to the      // next spot in cmdline_, add it to argv_/argc_ then update cmdchars      // to account for the copied-in token and its nul terminator.      strcpy (&this->cmdline_[cmdchars], token);      this->argv_[this->argc_] = &this->cmdline_[cmdchars];      ++this->argc_;      cmdchars += (strlen (token) + 1);    }  char libspec[1024];  sprintf (libspec, "%s.dll", name);  if ((this->dll_handle_ = LoadLibrary (libspec)) == NULL)    return format_errmsg (GetLastError (), libspec);  this->entry_ = (TEST_FUNC) GetProcAddress (this->dll_handle_, "main");  if (this->entry_ == NULL)    {      msg = format_errmsg (GetLastError (), "main");      this->cleanup ();      return msg;    }  else    {      unsigned int thread_id; /* unused */      uintptr_t h = _beginthreadex (0,             // security                                    1024 * 1024,   // stack size                                    run_test,      // entrypoint                                    (void *)this,  // arglist                                    0,             // initflag                                    &thread_id);   // thread ID      this->thr_handle_ = (HANDLE) h;      if (h == 0)         // Test thread may have access to thr_handle_        {          msg = format_errmsg (GetLastError (), "spawn");          this->cleanup ();          return msg;        }    }  return 0;}boolTest::status (int *exit_status){  if (this->running_)    return false;   // still running  *exit_status = this->status_;  this->cleanup ();  return true;}intTest::wait (void){  WaitForSingleObject (this->thr_handle_, INFINITE);  if (!this->running_)    this->cleanup ();  return this->status_;}voidTest::kill (void){  TerminateThread (this->thr_handle_, -1);  this->cleanup ();  this->running_ = false;  this->status_  = -1;}// Clean up remnants of a test run.voidTest::cleanup (void){  if (this->dll_handle_ != NULL)    {      FreeLibrary (this->dll_handle_);      this->dll_handle_ = NULL;    }  if (this->thr_handle_ != 0)    {      CloseHandle (this->thr_handle_);      this->thr_handle_ = 0;    }  this->entry_   = 0;  this->argc_ = 0;  for (int i = 0; i < ARGV_SIZE; ++i)    this->argv_[i] = 0;  memset (this->cmdline_, 0, CMDLINE_LEN);}static unsigned int __stdcalltest_control (void * /* param */){  // cd to ace dir?? (can this be an env variable?)  // redirect stdout/stderr to a file  logf = CreateFile (LogName,                     FILE_ALL_ACCESS,                     FILE_SHARE_READ,                     0,                  // security                     OPEN_ALWAYS,        // Don't crush a previous one                     FILE_ATTRIBUTE_NORMAL,                     0);  if (logf == INVALID_HANDLE_VALUE)    perror (LogName);  else    {      SetFilePointer (logf, 0, 0, FILE_END);   // Append new content      SetStdHandle (STD_OUTPUT_HANDLE, logf);      SetStdHandle (STD_ERROR_HANDLE, logf);    }  WORD want;  WSADATA offer;  want = MAKEWORD (2, 2);  if (0 != WSAStartup (want, &offer))    {      perror ("WSAStartup");      CloseHandle (logf);      return WSAGetLastError ();    }  // listen on port 8888 (can I set an env variable for this?)  SOCKET acceptor = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);  sockaddr_in listen_addr;  memset (&listen_addr, 0, sizeof (listen_addr));  listen_addr.sin_family = AF_INET;  listen_addr.sin_addr.s_addr = INADDR_ANY;  listen_addr.sin_port = htons (8888);  if (SOCKET_ERROR == bind (acceptor,                            (struct sockaddr *)&listen_addr,                            sizeof (listen_addr)))    {      perror ("bind");    }  else    {      listen (acceptor, 10);      SOCKET peer;      while ((peer = accept (acceptor, 0, 0)) != INVALID_SOCKET)        {          Peer *p = new Peer (peer);          if (p == 0)            {              perror ("Out of memory");              closesocket (peer);              peer = INVALID_SOCKET;              continue;            }          if (0 == _beginthreadex (0,            // security                                   64 * 1024,    // stack size                                   peer_svc,     // entrypoint                                   (void *)p,    // param                                   0,            // creation flags                                   0))           // ptr to thread id            {              perror ("beginthreadex peer");              closesocket (peer);              delete p;            }          p = 0;          peer = INVALID_SOCKET;        }      perror ("accept");    }  closesocket (acceptor);  WSACleanup ();  return 0;}// Entrypoint for thread that's spawned to run a peer's session. Direct// control to the peer class.static unsigned int __stdcallpeer_svc (void *peer_p){  Peer *p = (Peer *)peer_p;  DWORD status = p->svc ();  delete p;  return status;}// Entrypoint for the thread spawned to run a test. The thread arg is the// Test * - call back to the test's run() method; return the test exit code// as the thread's return value.static unsigned int __stdcallrun_test (void *test_p){  Test *t = (Test *)test_p;  return t->run ();}// Format a Windows system or Winsock error message given an error code.static const char *format_errmsg (unsigned int errcode, const char *prefix){  static const size_t errmsgsize = 1024;  static char errmsg[errmsgsize];  sprintf (errmsg, "%s: ", prefix);  size_t len = strlen (errmsg);  char *next = &errmsg[len];  size_t max_fmt = errmsgsize - len;  if (0 != FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM |                          FORMAT_MESSAGE_IGNORE_INSERTS,                          0,                          errcode,                          0,                 // Use default language                          next,                          (DWORD)max_fmt,                          0))    {      strcat (errmsg, "\n");      return errmsg;    }  errno = errcode;  char *msg = _strerror (prefix);  sprintf (errmsg, "err %d: %s", errcode, msg);  return errmsg;}#ifdef TEST_RUNNER_EXPORTS#define TEST_RUNNER_API __declspec(dllexport)#else#define TEST_RUNNER_API __declspec(dllimport)#endif__declspec(dllexport) int test_entry(void){  return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -