当前位置: 首页>>代码示例>>C++>>正文


C++ setIntegerParam函数代码示例

本文整理汇总了C++中setIntegerParam函数的典型用法代码示例。如果您正苦于以下问题:C++ setIntegerParam函数的具体用法?C++ setIntegerParam怎么用?C++ setIntegerParam使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。


在下文中一共展示了setIntegerParam函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。

示例1: asynPortDriver

/// XFCPort constructor
XFCPort::XFCPort(const char * name) : asynPortDriver(
        name,
        1, /* maxAddr */
        1, /* max parameters */
        asynInt32Mask | asynDrvUserMask, /* interface mask*/
        asynInt32Mask, /* interrupt mask */
        0, /* non-blocking, no addresses */
        1, /* autoconnect */
        0, /* default priority */
        0) /* default stack size */
{
    printf("Creating XFCPort \"%s\"\n", name);
    createParam("MISSED", asynParamInt32, &P_Missed);
    setIntegerParam(P_Missed, 0);
}
开发者ID:ronaldomercado,项目名称:ethercat,代码行数:16,代码来源:ecAsyn.cpp

示例2: releaseBlockLocks

void releaseBlockLocks(char* serviceName, int servicePort,
                       char* fileName, int lockID) {

    MessageClient client = newClient(serviceName, servicePort);
    Message m = newMessage();
    m->type = FILE_LOCK_CLIENT_SERVICE_CLIENT_MESSAGE;
    setStringParam(m, "functionName", "releaseblock");
    setStringParam(m, "fileName", fileName);
    setIntegerParam(m, "lockID", lockID);
    Message reply = clientCall(client, m);
    clientDisconnect(client);
    
    destroyMessage(m);
    destroyMessage(reply);
}
开发者ID:gkthiruvathukal,项目名称:st-hec,代码行数:15,代码来源:lockserverapi.c

示例3: getStringParam

void NDFileNexus::loadTemplateFile() {
  bool loadStatus;
  int addr = 0;
  char fullFilename[2*MAX_FILENAME_LEN] = "";
  char template_path[MAX_FILENAME_LEN] = "";
  char template_file[MAX_FILENAME_LEN] = "";
  static const char *functionName = "loadTemplateFile";

  /* get the filename to be used for nexus template */
  getStringParam(addr, NDFileNexusTemplatePath, sizeof(template_path), template_path);
  getStringParam(addr, NDFileNexusTemplateFile, sizeof(template_file), template_file);
  sprintf(fullFilename, "%s%s", template_path, template_file);
  if (strlen(fullFilename) == 0) return;

  /* Load the Nexus template file */
  loadStatus = this->configDoc.LoadFile(fullFilename);

  if (loadStatus != true ){
    asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
              "%s:%s: Parameter file %s is invalid\n",
              driverName, functionName, fullFilename);
    setIntegerParam(addr, NDFileNexusTemplateValid, 0);
    callParamCallbacks(addr, addr);
    return;
  }
  else {
    asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW,
              "%s:%s: Parameter file %s was successfully loaded\n",
              driverName, functionName, fullFilename);
    setIntegerParam(addr, NDFileNexusTemplateValid, 1);
    callParamCallbacks(addr, addr);
  }

  this->rootNode = this->configDoc.RootElement();

}
开发者ID:dhickin,项目名称:ADCore,代码行数:36,代码来源:NDFileNexus.cpp

示例4: while

void asynNDArrayDriver::updateQueuedArrayCount()
{
    while (queuedArrayUpdateRun_) {
        epicsEventWait(queuedArrayEvent_);
        // Exit early
        if (!queuedArrayUpdateRun_)
            break;

        lock();
        setIntegerParam(NDNumQueuedArrays, getQueuedArrayCount());
        callParamCallbacks();
        unlock();
    }
    epicsEventSignal(queuedArrayUpdateDone_);
}
开发者ID:areaDetector,项目名称:ADCore,代码行数:15,代码来源:asynNDArrayDriver.cpp

示例5: setIntegerParam

/** Called when asyn clients call pasynInt32->write().
  * For all parameters it sets the value in the parameter library and calls any registered callbacks..
  * \param[in] pasynUser pasynUser structure that encodes the reason and address.
  * \param[in] value Value to write. */
asynStatus DSA2000::writeInt32(asynUser *pasynUser, epicsInt32 value)
{
    int function = pasynUser->reason;
    asynStatus status = asynSuccess;
    struct ncp_hcmd_resethvstatus resetCommand;
    int sendStatus;
    int response;
    int actual;
    const char *paramName;
    const char* functionName = "writeInt32";

    /* Set the parameter in the parameter library. */
    setIntegerParam(function, value);

    /* Fetch the parameter string name for possible use in debugging */
    getParamName(function, &paramName);

    if (function == P_HVRangeSetting) {
        /* Set the range */
        status = setHVStatus();
    }
    if (function == P_HVReset) {
        /* Send the HV reset command */
        sendStatus = nmc_sendcmd(this->module, NCP_K_HCMD_RESETHVSTATUS, &resetCommand, sizeof(resetCommand),
                                 &response, sizeof(response), &actual, 0);
        if (sendStatus != 9) status = asynError;
    }
    else if (function == P_ReadStatus) {
        status = getHVStatus();
    }
    else {
        /* All other parameters just get set in parameter list, no need to
         * act on them here */
    }

    /* Do callbacks so higher layers see any changes */
    callParamCallbacks();

    if (status)
        epicsSnprintf(pasynUser->errorMessage, pasynUser->errorMessageSize,
                      "%s:%s: status=%d, function=%d, name=%s, value=%d",
                      driverName, functionName, status, function, paramName, value);
    else
        asynPrint(pasynUser, ASYN_TRACEIO_DRIVER,
                  "%s:%s: function=%d, name=%s, value=%d\n",
                  driverName, functionName, function, paramName, value);
    return status;
}
开发者ID:keenanlang,项目名称:mca,代码行数:52,代码来源:DSA2000.cpp

示例6: while

/** Callback task that runs as a separate thread. */
void testErrors::callbackTask(void)
{
    asynStatus currentStatus;
    epicsInt32 iVal;
    epicsFloat64 dVal;
    int i;
    char octetValue[20];
    
    /* Loop forever */    
    while (1) {
        lock();
        getIntegerParam(P_StatusReturn, (int*)&currentStatus);
        getIntegerParam(P_Int32Value, &iVal);
        iVal++;
        if (iVal > 15) iVal=0;
        setIntegerParam(P_Int32Value, iVal);
        setParamStatus(P_Int32Value, currentStatus);
        getDoubleParam(P_Float64Value, &dVal);
        dVal += 0.1;
        setDoubleParam(P_Float64Value, dVal);
        setParamStatus(P_Float64Value, currentStatus);
        sprintf(octetValue, "%.1f", dVal); 
        setParamStatus(P_UInt32DigitalValue, currentStatus);
        setStringParam(P_OctetValue, octetValue);
        setParamStatus(P_OctetValue, currentStatus);
        setParamStatus(P_Float64ArrayValue, currentStatus);
        for (i=0; i<MAX_ARRAY_POINTS; i++) {
            int8ArrayValue_[i]    = iVal;
            int16ArrayValue_[i]   = iVal;
            int32ArrayValue_[i]   = iVal;
            float32ArrayValue_[i] = dVal;
            float64ArrayValue_[i] = dVal;
        }
        callParamCallbacks();
        setParamStatus(P_Int8ArrayValue, currentStatus);
        doCallbacksInt8Array(int8ArrayValue_, MAX_ARRAY_POINTS, P_Int8ArrayValue, 0);
        setParamStatus(P_Int16ArrayValue, currentStatus);
        doCallbacksInt16Array(int16ArrayValue_, MAX_ARRAY_POINTS, P_Int16ArrayValue, 0);
        setParamStatus(P_Int32ArrayValue, currentStatus);
        doCallbacksInt32Array(int32ArrayValue_, MAX_ARRAY_POINTS, P_Int32ArrayValue, 0);
        setParamStatus(P_Float32ArrayValue, currentStatus);
        doCallbacksFloat32Array(float32ArrayValue_, MAX_ARRAY_POINTS, P_Float32ArrayValue, 0);
        setParamStatus(P_Float64ArrayValue, currentStatus);
        doCallbacksFloat64Array(float64ArrayValue_, MAX_ARRAY_POINTS, P_Float64ArrayValue, 0);
        unlock();
        epicsThreadSleep(CALLBACK_PERIOD);
    }
}
开发者ID:BCDA-APS,项目名称:epicsEdgeRoboArm,代码行数:49,代码来源:testErrors.cpp

示例7: asynPrint

// Jog
asynStatus SMC100Axis::moveVelocity(double minVelocity, double maxVelocity, double acceleration)
{
  double high_limit;
  double low_limit;
  asynStatus comStatus;
  static const char *functionName = "SMC100Axis::moveVelocity";

  asynPrint(pasynUser_, ASYN_TRACE_FLOW,
    "%s: minVelocity=%f, maxVelocity=%f, acceleration=%f\n",
    functionName, minVelocity, maxVelocity, acceleration);
    
  comStatus = sendAccelAndVelocity(acceleration, maxVelocity);
  if (comStatus) goto skip;

  /* SMC100 supports the notion of jog, but only for a remote control keypad */
  // SMC100 will not allow moves outside of those set with the SL and SR commands
  // first we query these limits and then make the jog a move to the limit
  
  // get the high limit
  sprintf(pC_->outString_, "%1dSR?", axisNo_ + 1);
  comStatus = pC_->writeReadController();
  if (comStatus) goto skip;
  // The response string is of the form "1SR25.0"
  high_limit = (atof(&pC_->inString_[3]));
  
    // get the low limit
  sprintf(pC_->outString_, "%1dSL?", axisNo_ + 1);
  comStatus = pC_->writeReadController();
  if (comStatus) goto skip;
  // The response string is of the form "1SL-5.0"
  low_limit = (atof(&pC_->inString_[3]));
  
  if (maxVelocity > 0.) {
    /* This is a positive move in SMC100 coordinates (egus) */
    sprintf(pC_->outString_, "%1dPA%f", axisNo_ + 1, high_limit);
  } else {
      /* This is a negative move in SMC100 coordinates (egus) */
      sprintf(pC_->outString_, "%1dPA%f", axisNo_ + 1, low_limit);
  }
  comStatus = pC_->writeController();
  if (comStatus) goto skip;
  
  skip:
  setIntegerParam(pC_->motorStatusProblem_, comStatus ? 1:0);
  callParamCallbacks();
  return comStatus ? asynError : asynSuccess;

}
开发者ID:ISISComputingGroup,项目名称:EPICS-motor,代码行数:49,代码来源:SMC100Driver.cpp

示例8: setIntegerParam

asynStatus NDPluginFile::writeNDArray(asynUser *pasynUser, void *genericPointer)
{
    NDArray *pArray = (NDArray *)genericPointer;
    asynStatus status = asynSuccess;
    //static const char *functionName = "writeNDArray";
        
    this->pArrays[0] = pArray;
    setIntegerParam(NDFileWriteMode, NDFileModeSingle);

    status = writeFileBase();

    /* Do callbacks so higher layers see any changes */
    status = callParamCallbacks();
    
    return status;
}
开发者ID:prjemian,项目名称:ADCore,代码行数:16,代码来源:NDPluginFile.cpp

示例9: sprintf

////////////////////////////////////////
//! writeController()
//! reference ACRMotorDriver
//
//! Writes a string to the IMS controller.
//! Prepends deviceName to command string, if party mode not enabled, set device name to ""
//! @param[in] output the string to be written.
//! @param[in] timeout Timeout before returning an error.
////////////////////////////////////////
asynStatus ImsMDrivePlusMotorController::writeController(const char *output, double timeout)
{
	size_t nwrite;
	asynStatus status;
	char outbuff[MAX_BUFF_LEN];
	static const char *functionName = "writeController()";

	// in party-mode Line Feed must follow command string
	sprintf(outbuff, "%s%s", deviceName, output);
	asynPrint(pasynUserSelf, ASYN_TRACEIO_DRIVER, "%s:%s: deviceName=%s, command=%s\n", DRIVER_NAME, functionName, deviceName, outbuff);
	status = pasynOctetSyncIO->write(pAsynUserIMS, outbuff, strlen(outbuff), timeout, &nwrite);
	if (status) { // update comm flag
		setIntegerParam(this->motorStatusCommsError_, 1);
	}
	return status ;
}
开发者ID:epicsdeb,项目名称:synapps,代码行数:25,代码来源:ImsMDrivePlusMotorController.cpp

示例10: sprintf

/** Polls the axis.
  * This function reads the motor position, the limit status, the home status, the moving status, 
  * and the drive power-on status. 
  * It calls setIntegerParam() and setDoubleParam() for each item that it polls,
  * and then calls callParamCallbacks() at the end.
  * \param[out] moving A flag that is set indicating that the axis is moving (true) or done (false). */
asynStatus MCB4BAxis::poll(bool *moving)
{ 
  int done;
  int driveOn;
  int limit;
  double position;
  asynStatus comStatus;

  // Read the current motor position
  sprintf(pC_->outString_, "#%02dP", axisNo_);
  comStatus = pC_->writeReadController();
  if (comStatus) goto skip;
  // The response string is of the form "#01P=+1000"
  position = atof(&pC_->inString_[5]);
  setDoubleParam(pC_->motorPosition_, position);

  // Read the moving status of this motor
  sprintf(pC_->outString_, "#%02dX", axisNo_);
  comStatus = pC_->writeReadController();
  if (comStatus) goto skip;
  // The response string is of the form "#01X=1"
  done = (pC_->inString_[5] == '0') ? 1:0;
  setIntegerParam(pC_->motorStatusDone_, done);
  *moving = done ? false:true;

  // Read the limit status
  sprintf(pC_->outString_, "#%02dE", axisNo_);
  comStatus = pC_->writeReadController();
  if (comStatus) goto skip;
  // The response string is of the form "#01E=1"
  limit = (pC_->inString_[5] == '1') ? 1:0;
  setIntegerParam(pC_->motorStatusHighLimit_, limit);
  limit = (pC_->inString_[6] == '1') ? 1:0;
  setIntegerParam(pC_->motorStatusLowLimit_, limit);
  limit = (pC_->inString_[7] == '1') ? 1:0;
  setIntegerParam(pC_->motorStatusAtHome_, limit);

  // Read the drive power on status
  sprintf(pC_->outString_, "#%02dE", axisNo_);
  comStatus = pC_->writeReadController();
  if (comStatus) goto skip;
  driveOn = (pC_->inString_[5] == '1') ? 1:0;
  setIntegerParam(pC_->motorStatusPowerOn_, driveOn);
  setIntegerParam(pC_->motorStatusProblem_, 0);

  skip:
  setIntegerParam(pC_->motorStatusProblem_, comStatus ? 1:0);
  callParamCallbacks();
  return comStatus ? asynError : asynSuccess;
}
开发者ID:epicsdeb,项目名称:synapps,代码行数:56,代码来源:MCB4BDriver.cpp

示例11: asynPortDriver

/// Constructor for the FileList class.
/// Calls constructor for the asynPortDriver base class.
FileList::FileList(const char *portName, const char *searchDir, const char *searchPat, int fullPath) 
   : asynPortDriver(portName, 
                    4, /* maxAddr */ 
                    NUM_FileList_PARAMS,
					asynInt32Mask | asynOctetMask | asynDrvUserMask | asynFloat64Mask, /* Interface mask */
                    asynInt32Mask | asynOctetMask | asynFloat64Mask,  /* Interrupt mask */
                    0, /* asynFlags.  This driver can block but it is not multi-device */
                    1, /* Autoconnect */
                    0, /* Default priority */
                    0)	/* Default stack size*/,
	watchQueue_(10, sizeof(char *)), m_fullPath(fullPath != 0 ? true : false)
{
	int status = asynSuccess;
    const char *functionName = "FileList";

	createParam(P_DirBaseString, asynParamOctet, &P_DirBase);
	createParam(P_SearchString, asynParamOctet, &P_Search);
	createParam(P_CaseString, asynParamInt32, &P_CaseSensitive);
	createParam(P_JSONArrString, asynParamOctet, &P_JSONOutArr);

	//Allocate column data
	pJSONOut_ = (char *)calloc(OUT_CHAR_LIM, 1);

	setStringParam(P_DirBase, searchDir);
	setStringParam(P_Search, searchPat);
	setIntegerParam(P_CaseSensitive, 0);
	updateList();

	// Start filewatcher
	char * str = strdup(searchDir);
	watchQueue_.send((void*)&str, sizeof(char*));

	/* Do callbacks so higher layers see any changes */
	status |= (asynStatus)callParamCallbacks();

	// Create the thread that will service the file watcher
	// To write to the controller
	epicsThreadCreate("fileWatcher", 
                    epicsThreadPriorityMax,
                    epicsThreadGetStackSize(epicsThreadStackMedium),
                    (EPICSTHREADFUNC)fileWatcherThreadC, (void *)this);
	if (status) {
		std::cerr << status << "epicsThreadCreate failure" << std::endl;
		return;
	}

}
开发者ID:ISISComputingGroup,项目名称:EPICS-FileList,代码行数:49,代码来源:FileList.cpp

示例12: ShamrockGetGrating

asynStatus shamrock::getStatus()
{
    int error;
    asynStatus status;
    int grating;
    float wavelength;
    float width;
    int i;
    static const char *functionName = "getStatus";

    error = ShamrockGetGrating(shamrockId_, &grating);
    status = checkError(error, functionName, "ShamrockGetGrating");
    if (status) return asynError;
    setIntegerParam(SRGrating_, grating);

    error = ShamrockGetWavelength(shamrockId_, &wavelength);
    status = checkError(error, functionName, "ShamrockGetWavelength");
    if (status) return asynError;
    setDoubleParam(SRWavelength_, wavelength);

    for (i=0; i<MAX_SLITS; i++) {
        setDoubleParam(i, SRSlitSize_, 0.);
        if (slitIsPresent_[i] == 0) continue;
        error = ShamrockGetAutoSlitWidth(shamrockId_, i+1, &width);
        status = checkError(error, functionName, "ShamrockGetAutoSlitWidth");
        if (status) return asynError;
        setDoubleParam(i, SRSlitSize_, width);
    }
    
    error = ShamrockGetCalibration(shamrockId_, calibration_, numPixels_);
    status = checkError(error, functionName, "ShamrockGetCalibration");
    setDoubleParam(0, SRMinWavelength_, calibration_[0]);
    setDoubleParam(0, SRMaxWavelength_, calibration_[numPixels_-1]);
    // We need to find a C/C++ library to do 3'rd order polynomial fit
    // For now we do a first order fit!
    double slope = (calibration_[numPixels_-1] - calibration_[0]) / (numPixels_-1);

    for (i=0; i<MAX_ADDR; i++) {
        callParamCallbacks(i);
    }
    
    doCallbacksFloat32Array(calibration_, numPixels_, SRCalibration_, 0);

    return asynSuccess;
}
开发者ID:ISISComputingGroup,项目名称:EPICS-areaDetector,代码行数:45,代码来源:shamrock.cpp

示例13: getIntegerParam

/** This is called to write data a single NDArray to the file.  It can be called multiple times
 *  to add arrays to a single file in stream or capture mode */
asynStatus NDFileHDF5XML::writeFile(NDArray *pArray)
{
   unsigned long int stripsize;
   static const char *functionName = "writeFile";
   int sizex, sizey;
   int numToCapture;
   int imgc, nimg;
   int writeMode;

   sizex = pArray->dims[0].size;
   sizey = pArray->dims[1].size;

//NDFileFormat

   getIntegerParam(NDFileFormat, &fileformat);
   getIntegerParam(NDFileWriteMode, &writeMode);

//   pArray->pAttributeList->report(20);
   getAttributes(pArray->pAttributeList);
   hdf_interface->pArray = pArray;



   //This will write the image data...
   //!!lock();
   configDoc->Accept(hdf5Writer);
   //!!unlock();
   this->nextRecord++;

   setIntegerParam(NDFileNumCaptured, this->nextRecord);
   getIntegerParam(NDFileNumCapture, &numToCapture);
/*   if ((((writeMode == NDFileModeStream) || (writeMode == NDFileModeCapture)) &&
         this->nextRecord >= numToCapture) )
   {
      setIntegerParam(NDFileNumCaptured, numToCapture);
      hdf_interface->pArray = pArray;


      closeFile();

   }
*/
   return (asynSuccess);
}
开发者ID:Engbretson,项目名称:IMM_Plugin,代码行数:46,代码来源:NDFileHDF5XML.cpp

示例14: setIntegerParam

/** Called when asyn clients call pasynInt32->write().
  * This function sends a signal to the simTask thread if the value of P_Run has changed.
  * For all parameters it sets the value in the parameter library and calls any registered callbacks..
  * \param[in] pasynUser pasynUser structure that encodes the reason and address.
  * \param[in] value Value to write. */
asynStatus testAsynPortDriver::writeInt32(asynUser *pasynUser, epicsInt32 value)
{
    int function = pasynUser->reason;
    asynStatus status = asynSuccess;
    const char *paramName;
    const char* functionName = "writeInt32";

    /* Set the parameter in the parameter library. */
    status = (asynStatus) setIntegerParam(function, value);
    
    /* Fetch the parameter string name for possible use in debugging */
    getParamName(function, &paramName);

    if (function == P_Run) {
        /* If run was set then wake up the simulation task */
        if (value) epicsEventSignal(eventId_);
    } 
    else if (function == P_VertGainSelect) {
        setVertGain();
    }
    else if (function == P_VoltsPerDivSelect) {
        setVoltsPerDiv();
    }
    else if (function == P_TimePerDivSelect) {
        setTimePerDiv();
    }
    else {
        /* All other parameters just get set in parameter list, no need to
         * act on them here */
    }
    
    /* Do callbacks so higher layers see any changes */
    status = (asynStatus) callParamCallbacks();
    
    if (status) 
        epicsSnprintf(pasynUser->errorMessage, pasynUser->errorMessageSize, 
                  "%s:%s: status=%d, function=%d, name=%s, value=%d", 
                  driverName, functionName, status, function, paramName, value);
    else        
        asynPrint(pasynUser, ASYN_TRACEIO_DRIVER, 
              "%s:%s: function=%d, name=%s, value=%d\n", 
              driverName, functionName, function, paramName, value);
    return status;
}
开发者ID:ukaea,项目名称:epics,代码行数:49,代码来源:testAsynPortDriver.cpp

示例15: getStringParam

/** Checks whether the directory specified NDFilePath parameter exists.
  * 
  * This is a convenience function that determinesthe directory specified NDFilePath parameter exists.
  * It sets the value of NDFilePathExists to 0 (does not exist) or 1 (exists).  
  * It also adds a trailing '/' character to the path if one is not present.
  * Returns a error status if the directory does not exist.
  */
asynStatus asynNDArrayDriver::checkPath()
{
    /* Formats a complete file name from the components defined in NDStdDriverParams */
    asynStatus status = asynError;
    char filePath[MAX_FILENAME_LEN];
    char lastChar;
    int hasTerminator=0;
    struct stat buff;
    int istat;
    size_t len;
    int isDir=0;
    int pathExists=0;
    
    getStringParam(NDFilePath, sizeof(filePath), filePath);
    len = strlen(filePath);
    if (len == 0) return(asynSuccess);
    /* If the path contains a trailing '/' or '\' remove it, because Windows won't find
     * the directory if it has that trailing character */
    lastChar = filePath[len-1];
#ifdef _WIN32
    if ((lastChar == '/') || (lastChar == '\\'))
#else
    if (lastChar == '/') 
#endif
    {
        filePath[len-1] = 0;
        len--;
        hasTerminator=1;
    }
    istat = stat(filePath, &buff);
    if (!istat) isDir = (S_IFDIR & buff.st_mode);
    if (!istat && isDir) {
        pathExists = 1;
        status = asynSuccess;
    }
    /* If the path did not have a trailing terminator then add it if there is room */
    if (!hasTerminator) {
        if (len < MAX_FILENAME_LEN-2) strcat(filePath, delim);
        setStringParam(NDFilePath, filePath);
    }
    setIntegerParam(NDFilePathExists, pathExists);
    return status;   
}
开发者ID:waynelewis,项目名称:ADCore,代码行数:50,代码来源:asynNDArrayDriver.cpp


注:本文中的setIntegerParam函数示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。