cc.debug源码及使用

本文深入研究了Cocos Creator的cc.debug模块,包括cc.debug的函数列表、初始化、resetDebugSetting的实现,特别是日志等级(DebugMode)与bind(console)的原因。此外,还探讨了cc.debug模块的属性,如FPS信息、游戏内日志输出、cc.logID及其工作原理。文章最后讨论了cc._throw函数的用途。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

cc.debug研究

CCDebug.js:cocos2d\core\CCDebug.js

相关函数

函数列表

方法名作用参数
cc.log普通输出(msg: string/any, …subst: any[])
cc.warn警告类型输出,chrome中有黄色背景,黄色警告图标
cc.error错误类型输出,chrome中有红色背景,红色错误图标
cc.assert断言性输出,当传入的condition为false时才起作用,本质上是cc.error,在调试模式并在chrome中时,会有程序运行挂起的效果,继续运行会跳过后续代码。有助于debug。(condition?: boolean, …data: any[])

测试代码

onLoad () {
  cc.log("这是一条log");
  cc.warn("这是一条warn");
  cc.error("这是一条error");
  cc.log("这是一条log", 111, "其他信息");
  cc.assert(true, "这是第一条assert");
  cc.assert(false, "这是第二条assert");
  cc.log("该行代码被跳过");
},
  
start () {
  cc.log("这是一条log start");
},

测试结果

在Cocos Creator中,点击运行预览按钮(工具栏上类似播放键的那个)使用浏览器模式,预览。
image.png
运行到cc.assert(false, “这是第二条assert”);时,被挂起。
image.png
点击顶部蓝色按钮继续运行。

  • 第一条cc.assert中,由于传入第一个参数为true,故没有任何效果。
  • 继续运行后,后续的代码被跳过,但不会影响其他地方的代码,如start()中的输出语句。
  • 输出/运行效果(如颜色)在不同的浏览器/运行环境下可能不同。

代码实现

日志等级(DebugMode)

枚举名作用
0NONE禁止模式,啥也不打印
1INFO信息模式,啥都打印
2WARN警告模式,警告及以上打印
3ERROR错误模式,仅打印错误
4INFO_FOR_WEB_PAGE在画面上输出,同INFO(仅WEB端下生效)
5WARN_FOR_WEB_PAGE在画面上输出,同WARN(仅WEB端下生效)
6ERROR_FOR_WEB_PAGE在画面上输出,同ERROR(仅WEB端下生效)

后面三种模式其实和前面的是一样的,但只有在Web端才生效,因为打印到画面的实现方法是,使用代码动态创建一个HTML节点,并将日志文本输出到节点中,所以在其他端无法使用。

初始化

// CCGame.js		cocos2d\core\CCGame.js
_initConfig (config) {
  // 若输入不合法的debugMode 修改为0(DebugMode.NONE 啥等级的也不显示)
  if (typeof config.debugMode !== 'number') {
    config.debugMode = 0;
  }
  // 此处省略部分代码
 	// 调用_resetDebugSetting方法进行初始化,此处的debugMode默认为cc.debug.DebugMode.INFO
  // DebugMode.INFO:显示所有日志
  debug._resetDebugSetting(config.debugMode);
}

resetDebugSetting

// CCDebug.js		cocos2d\core\CCDebug.js
module.exports = cc.debug = {
  // 此处省略部分代码
    _resetDebugSetting: resetDebugSetting,
}

let resetDebugSetting = function (mode) {
    // reset
 		// 重置各个方法,这就是设置日志等级的核心所在。
  	// 重置后再根据mode参数给对应的方法赋值,即实现了只打印部分等级日志。
    cc.log = cc.warn = cc.error = cc.assert = function () {};
		
  	// 啥也不打印 所以直接return 哪个方法都不配置
    if (mode === DebugMode.NONE)
        return;
  
		// 当mode大于ERROR的时候 是要将日志打印到画面中
    if (mode > DebugMode.ERROR) {
        //log to web page

      	// 把日志打印到游戏画面上
      	// 用代码创建一个div节点,固定在左上角,里面放一个textarea,然后把日志写到textarea里
     		// 日志打印到一个textarea,所以还可以拖动改大小 妙啊
      	// 是不是可以把创建节点的代码挪到外面去?这样就可以不用每次都判断是否存在logList
        function logToWebPage (msg) {
            if (!cc.game.canvas)
                return;

            if (!logList) {
                var logDiv = document.createElement("Div");
                logDiv.setAttribute("id", "logInfoDiv");
                logDiv.setAttribute("width", "200");
                logDiv.setAttribute("height", cc.game.canvas.height);
                var logDivStyle = logDiv.style;
                logDivStyle.zIndex = "99999";
                logDivStyle.position = "absolute";
                logDivStyle.top = logDivStyle.left = "0";

                logList = document.createElement("textarea");
                logList.setAttribute("rows", "20");
                logList.setAttribute("cols", "30");
                logList.setAttribute("disabled", "true");
                var logListStyle = logList.style;
                logListStyle.backgroundColor = "transparent";
                logListStyle.borderBottom = "1px solid #cccccc";
                logListStyle.borderTopWidth = logListStyle.borderLeftWidth = logListStyle.borderRightWidth = "0px";
                logListStyle.borderTopStyle = logListStyle.borderLeftStyle = logListStyle.borderRightStyle = "none";
                logListStyle.padding = "0px";
                logListStyle.margin = 0;

                logDiv.appendChild(logList);
                cc.game.canvas.parentNode.appendChild(logDiv);
            }

            logList.value = logList.value + msg + "\r\n";
            logList.scrollTop = logList.scrollHeight;
        }
				
      	// 修改cc.error和cc.assert的实现,均为调用上面的logToWebPage方法
      	// 输出到画面上固然不错,但缺点就是只能通过添加等级前缀,不能通过颜色清晰标识不同等级的日志
        cc.error = function () {
          	// cc.js.formatStr: 格式化字符串 不太相干,但是觉得蛮有意思的,写在最后https://www.yuque.com/yuhuo-2kehw/ehcgn5/klfugv#6TajH
            logToWebPage("ERROR :  " + cc.js.formatStr.apply(null, arguments));
        };
        cc.assert = function (cond, msg) {
            'use strict';
            if (!cond && msg) {
                msg = cc.js.formatStr.apply(null, cc.js.shiftArguments.apply(null, arguments));
                logToWebPage("ASSERT: " + msg);
            }
        };
      	// 等级不是只输出ERROR及以上,那就可以设置cc.warn
        if (mode !== DebugMode.ERROR_FOR_WEB_PAGE) {
            cc.warn = function () {
                logToWebPage("WARN :  " + cc.js.formatStr.apply(null, arguments));
            };
        }
      	// 等级是输出INFO及以上,那就可以设置cc.log
        if (mode === DebugMode.INFO_FOR_WEB_PAGE) {
            cc.log = function () {
                logToWebPage(cc.js.formatStr.apply(null, arguments));
            };
        }
    }
    else if (console && console.log.apply) {
      	//console is null when user doesn't open dev tool on IE9
        //log to console
      	// 输出日志到控制台。在使用IE9的时候,若没有打开dev tool,console为null

        // For JSB
      	// 兼容JSB??为了JSB??
        if (!console.error) console.error = console.log;
        if (!console.warn) console.warn = console.log;

        /**
         * !#en
         * Outputs an error message to the Cocos Creator Console (editor) or Web Console (runtime).<br/>
         * - In Cocos Creator, error is red.<br/>
         * - In Chrome, error have a red icon along with red message text.<br/>
         * !#zh
         * 输出错误消息到 Cocos Creator 编辑器的 Console 或运行时页面端的 Console 中。<br/>
         * - 在 Cocos Creator 中,错误信息显示是红色的。<br/>
         * - 在 Chrome 中,错误信息有红色的图标以及红色的消息文本。<br/>
         *
         * @method error
         * @param {any} msg - A JavaScript string containing zero or more substitution strings.
         * @param {any} ...subst - JavaScript objects with which to replace substitution strings within msg. This gives you additional control over the format of the output.
         */
      	// 如果是编辑器模式,则error输出到CocosCreator里的控制台
        if (CC_EDITOR) {
            cc.error = Editor.error;
        }
        else if (console.error.bind) {
            // use bind to avoid pollute call stacks
          	// 使用bind以避免污染调用栈。
          	// 先判断是否有bind方法,是因为在某些js引擎中,log不支持bind函数(极少数情况下才会如此)。
          	// 至于为什么要bind(console),后面会展开
            cc.error = console.error.bind(console);
        }
        else {
          	// 若运行在原生环境下(CC_JSB)或运行时环境(CC_RUNTIME)下,使用console.error
          	// 否则使用apply函数调用,并传递this为console
            cc.error = CC_JSB || CC_RUNTIME ? console.error : function () {
                return console.error.apply(console, arguments);
            };
        }
        cc.assert = function (cond, msg) {
          	// 当cond为false时,才执行日志输出
            if (!cond) {
                if (msg) {
                    msg = cc.js.formatStr.apply(null, cc.js.shiftArguments.apply(null, arguments));
                }
                if (CC_DEV) {
                  	// 开发环境下,会挂起程序运行,这就是测试结果中提到的被挂起,方便调试
                    debugger;
                }
                if (CC_TEST) {
                  	// 单元测试环境下,调用ok函数,应该是用于输出测试结果,定义于test\qunit\lib\qunit.js
                    ok(false, msg);
                }
                else {
                  	// 抛出错误
                    throw new Error(msg);
                }
            }
        }
    }
  	// 不是仅输出ERROR及以上 定义cc.warn
  	// 内容大多和上面的cc.error类似
    if (mode !== DebugMode.ERROR) {
        /**
         * !#en
         * Outputs a warning message to the Cocos Creator Console (editor) or Web Console (runtime).
         * - In Cocos Creator, warning is yellow.
         * - In Chrome, warning have a yellow warning icon with the message text.
         * !#zh
         * 输出警告消息到 Cocos Creator 编辑器的 Console 或运行时 Web 端的 Console 中。<br/>
         * - 在 Cocos Creator 中,警告信息显示是黄色的。<br/>
         * - 在 Chrome 中,警告信息有着黄色的图标以及黄色的消息文本。<br/>
         * @method warn
         * @param {any} msg - A JavaScript string containing zero or more substitution strings.
         * @param {any} ...subst - JavaScript objects with which to replace substitution strings within msg. This gives you additional control over the format of the output.
         */
        if (CC_EDITOR) {
            cc.warn = Editor.warn;
        }
        else if (console.warn.bind) {
            // use bind to avoid pollute call stacks
            cc.warn = console.warn.bind(console);
        }
        else {
            cc.warn = CC_JSB || CC_RUNTIME ? console.warn : function () {
                return console.warn.apply(console, arguments);
            };
        }
    }
  	// 编辑器模式下 保持cc.log可用 输出到Cocos Creator的控制台中
    // 这里有点不解CC_EDITOR指的是在哪运行,测试过程中 模拟器和网页预览 均为false。还可以在引擎内跑预览了?
  	// 后面的定义也大多和上面的类似
    if (CC_EDITOR) {
        cc.log = Editor.log;
    }
    else if (mode === DebugMode.INFO) {
        /**
         * !#en Outputs a message to the Cocos Creator Console (editor) or Web Console (runtime).
         * !#zh 输出一条消息到 Cocos Creator 编辑器的 Console 或运行时 Web 端的 Console 中。
         * @method log
         * @param {String|any} msg - A JavaScript string containing zero or more substitution strings.
         * @param {any} ...subst - JavaScript objects with which to replace substitution strings within msg. This gives you additional control over the format of the output.
         */
        if (CC_JSB || CC_RUNTIME) {
            if (scriptEngineType === "JavaScriptCore") {
                // console.log has to use `console` as its context for iOS 8~9. Therefore, apply it.
              	// iOS 8~9中,log函数必须使用console作为它的上下文(this),所以使用apply指定this
                cc.log = function () {
                    return console.log.apply(console, arguments);
                };
            } else {
                cc.log = console.log;
            }
        }
        else if (console.log.bind) {
            // use bind to avoid pollute call stacks
            cc.log = console.log.bind(console);
        }
        else {
            cc.log = function () {
                return console.log.apply(console, arguments);
            };
        }
    }
};

为什么bind(console)
cc.error = console.error.bind(console);

不论是cc.error还是.log .warn均有类似的写法。一开始很不解,看不出来有什么作用,在stackoverflow中找到一个说的还不错的,试着自己说说理解。先贴链接What does this statement do? console.log.bind(console)
其中有一段比较重要的

Suppose you wanted a shorter form of console.log, like f. You might do this:

var f = console.log; // <== Suspect!

…but if the log function relies on this referring to the console object during the call, then calling f("Message here") won’t work, because this won’t refer to console.

翻译:如果log方法需要this指向console对象,那么当你调用f()函数的时候,就无法实现你想要的效果(输出信息),因为this不指向console。
为什么需要this指向console呢… 想弄明白怕是要去研究引擎… 故先放下。继续看源码发现,源码中已有说明,在cc.log的赋值中有这样一句注释

console.log has to use console as its context for iOS 8~9. Therefore, apply it.

大概便是为了兼容ios8~9,才做了这番操作。当然,或许也有其他引擎需要做兼容,这里便不深入研究了…

cc.debug模块属性

属性名类型作用参数备注
DebugModecc.Enum调试模式 枚举类型 用于过滤显示日志的级别
getErrorfunction通过 error id和一些参数来生成错误信息(errorId: string, param?: any)实际上是CCDebug中的getTypedFormatter方法
isDisplayStatsfunction是否显示FPS相关信息的分析工具,在左下角
setDisplayStatsfunction与上一个方法对应。用于设置显示状态(displayStats: boolean)
_resetDebugSettingfunction重置调试相关的设置(mode: DebugMode)

DebugMode和_resetDebugSetting上面已经写过,下面来看一下FPS信息(DisplayStats)和一些其他内容

FPS信息(分析工具)

module.exports = cc.debug = {
 		// 省略部分代码
    /**
     * !#en Returns whether or not to display the FPS informations.
     * !#zh 是否显示 FPS 信息。
     * @method isDisplayStats
     * @return {Boolean}
     */
    isDisplayStats: function () {
        return cc.profiler ? cc.profiler.isShowingStats() : false;
    },

    /**
     * !#en Sets whether display the FPS on the bottom-left corner.
     * !#zh 设置是否在左下角显示 FPS。
     * @method setDisplayStats
     * @param {Boolean} displayStats
     */
    setDisplayStats: function (displayStats) {
        if (cc.profiler && cc.game.renderType !== cc.game.RENDER_TYPE_CANVAS) {
            displayStats ? cc.profiler.showStats() : cc.profiler.hideStats();
            cc.game.config.showFPS = !!displayStats;
        }
    },
}

cc.profiler是实现FPS分析工具的模块,定义于cocos2d\core\utils\profiler\CCProfiler.js
内容包括FPS、Draw Call、Frame time等
网页预览和模拟器会显示FPS界面,小游戏中没有,故推测是一些平台下不会有这个模块,所以需要先判断有没有cc.profiler
实现原理是监听事件然后记录、计算、刷新界面。展开看起来也可以写挺长的…这里就不展开了

// 省略了部分代码
cc.profiler = module.exports = {
  showStats () {
    cc.director.on(cc.Director.EVENT_BEFORE_UPDATE, beforeUpdate);
    cc.director.on(cc.Director.EVENT_AFTER_UPDATE, afterUpdate);
    cc.director.on(cc.Director.EVENT_AFTER_DRAW, afterDraw);
  }
}

其他内容

cc.js.formatStr

// js.js		cocos2d\core\platform\js.js
var REGEXP_NUM_OR_STR = /(%d)|(%s)/;
var REGEXP_STR = /%s/;

/**
 * A string tool to construct a string with format string.
 * @method formatStr
 * @param {String|any} msg - A JavaScript string containing zero or more substitution strings (%s).
 * @param {any} ...subst - JavaScript objects with which to replace substitution strings within msg. This gives you additional control over the format of the output.
 * @returns {String}
 * @example
 * cc.js.formatStr("a: %s, b: %s", a, b);
 * cc.js.formatStr(a, b, c);
 * 一个构造有格式化字符串的字符串工具 翻的好拗口...
 * 后面的举例更容易看懂,其实就是类似于c语言中的输出里的转换说明符吧
 */
js.formatStr = function () {
    var argLen = arguments.length;
    if (argLen === 0) {
        return '';
    }
    var msg = arguments[0];
    if (argLen === 1) {
        return '' + msg;
    }
		
  	// 是否需要替换,当msg是string且正则表达式匹配得到的情况下为true
    var hasSubstitution = typeof msg === 'string' && REGEXP_NUM_OR_STR.test(msg);
    if (hasSubstitution) {
      	// 遍历参数列表,把msg中的%d或%s替换为参数
        for (let i = 1; i < argLen; ++i) {
            var arg = arguments[i];
            var regExpToTest = typeof arg === 'number' ? REGEXP_NUM_OR_STR : REGEXP_STR;
            
          	// 如果匹配到%d或%s 把arg替换到文本中,否则把arg添加到msg末尾
          	if (regExpToTest.test(msg)) {
                const notReplaceFunction = '' + arg;
                msg = msg.replace(regExpToTest, notReplaceFunction);
            }
            else
                msg += ' ' + arg;
        }
    }
    else {
      	// 如若不需要替换 则把参数全部加到msg末尾
        for (let i = 1; i < argLen; ++i) {
            msg += ' ' + arguments[i];
        }
    }
    return msg;
};

游戏内日志输出

cc.debug._resetDebugSetting(cc.debug.DebugMode.INFO_FOR_WEB_PAGE);
cc.log("这是一条log");
cc.warn("这是一条warn");
cc.error("这是一条error");

image.png
问题来了… 为什么warn没有生效? 查看控制台,发现warn被打印到控制台上了
image.png
回去查看源码,发现在定义warn方法的时候,判断的是

if (mode !== DebugMode.ERROR)

所以warn函数在INFO_FOR_WEB_PAGE模式下,会被覆盖成输出到控制台
而定义log函数的时候,判断的是

if (CC_EDITOR) {
    cc.log = Editor.log;
}
else if (mode === DebugMode.INFO) {

所以info函数在INFO_FOR_WEB_PAGE模式下不会被覆盖
这算一个bug吗?

cc.logID

类似的方法有

  • cc.logID
  • cc.warnID
  • cc.errorID
  • cc.assertID

在内部其实调用的也是对应的cc.xxx方法,如cc.logId调用cc.log
拿cc.logId出来分析就好。实现的功能是根据id找到对应的错误信息,然后打印日志

// 创建一个日志格式化器
var logFormatter = getTypedFormatter('Log');
cc.logID = function () {
  	// 调用log方法输出内容
    cc.log(logFormatter.apply(null, arguments));
};
function getTypedFormatter (type) {
  	// 这里会有一个闭包,后面调用logID函数的时候,type都是Log,其他函数也会有对应的type文本。
    return function () {
        var id = arguments[0];
      	// 根据id设置错误信息
      	// 非调试模式下,msg包含type,id,以及cocos错误信息的链接
      	// const debugInfos = require('../../DebugInfos') || {};
        var msg = CC_DEBUG ? (debugInfos[id] || 'unknown id') : `${type} ${id}, please go to ${ERROR_MAP_URL}#${id} to see details.`;
        if (arguments.length === 1) {
            return msg;
        }
        else if (arguments.length === 2) {
          	// 有两个参数,把第二个参数连接到日志信息后面
            return CC_DEBUG ? cc.js.formatStr(msg, arguments[1]) :
                msg + ' Arguments: ' + arguments[1];
        }
        else {
          	// 有多个参数,把参数使用", "连接,添加到日志信息后面
            var argsArray = cc.js.shiftArguments.apply(null, arguments);
            return CC_DEBUG ? cc.js.formatStr.apply(null, [msg].concat(argsArray)) :
                msg + ' Arguments: ' + argsArray.join(', ');
        }
    };
}

debugInfos定义于"…/…/DebugInfos",但我没有在源码里找到这个文件…
在源码里的错误代码说明文件是EngineErrorMap.md
这个方法主要是用于提示cocos引擎内部的一些错误/提示,所以平时估计也用不上。但可以参考这些方法做一个自己的错误信息表。

试试看效果
// 测试代码
cc.errorID(1400, 'cc.info', 'cc.log');

// EngineErrorMap.md
### 1400
'%s' is deprecated, please use '%s' instead.

image.png
可以看到读取了错误代码对应的信息,且字符串中的%s被替换为后面的参数内容
还有就是cc.debug.getError也是使用类似的实现

getError: getTypedFormatter('ERROR')

cc._throw

// 编辑器模式下 输出error到Cocos Creator的控制台中
// 否则使用callInNextTick,在执行完当前代码后,执行回调,抛出错误
cc._throaw = CC_EDITOR ? Editor.error : function (error) {
    utils.callInNextTick(function () {
        throw error;
    });
};
尝试一下
cc._throw("抛出一个异常");

image.png
这个函数在cocos引擎中调用的地方不多,多是在try catch中调用,以抛出异常。

收尾

  • ccdebug模块的代码其实不多,但还蛮有意思的,尤其是发现可以在游戏界面打日志… 我也不知道在有意思个什么(淦)
  • 对于FPS分析工具,一开始没有多想,看到源码之后,却突然很想仔细研究一下实现,或许有机会?
  • 水平有限,若有纰漏还望各位大佬指正
### TensorFlow C++ DLL 文件 `tensorflow_cc.dll` 的下载与错误解决方案 #### 背景分析 在构建基于 TensorFlow 的 C++ 应用程序时,可能会遇到链接器错误(如 LNK2001),这通常是因为缺少必要的符号定义或未正确配置项目环境。对于 `tensorflow_cc.dll`,它是一个支持 TensorFlow C++ API 的动态链接库文件,主要用于加载和运行 TensorFlow 图形模型。 以下是针对该问题的具体解决方法: --- #### 解决方案一:手动编译生成 `tensorflow_cc.dll` 如果官方没有提供预编译版本的 `tensorflow_cc.dll`,可以通过源码自行编译生成所需的 `.dll` 和 `.lib` 文件。 1. **安装依赖工具** - 安装 Visual Studio 并启用 CMake 支持。 - 配置 Python 环境并安装 Bazel 构建工具[^1]。 2. **克隆 TensorFlow 源码** 使用以下命令获取最新版 TensorFlow 源码: ```bash git clone https://github.com/tensorflow/tensorflow.git cd tensorflow ``` 3. **应用补丁** 如果需要特定平台的支持(如 Windows MSVC 编译器),可以复制补丁文件到指定位置以优化编译过程: ```powershell Copy-Item ...\patches\tf_exported_symbols_msvc.lds tensorflow\ ``` 4. **执行 CMake 构建流程** 进入 TensorFlow 源码目录后,通过 CMake 工具生成项目的 Makefile 或 VS Solution 文件: ```cmd cmake .. -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON ``` 此操作会生成共享库文件 `tensorflow_cc.dll` 及其对应的静态库文件 `tensorflow.lib`[^3]。 5. **定位生成的文件** 成功编译后,可以在以下路径找到目标文件: ``` ..\tensorflow\tensorflow\contrib\cmake\build\Release ``` 6. **设置头文件路径** 将头文件路径指向 TensorFLow 提供的标准接口目录: ``` tensorflow-master\bazel-bin\tensorflow\include ``` --- #### 解决方案二:修复链接器错误 LNK2001 当出现类似于 `LNK2001: unresolved external symbol` 的错误时,可能的原因包括但不限于以下几点: 1. **缺失的函数声明** 确保所有使用的类成员函数均已实现,并且调用了正确的命名空间前缀。例如,在 TensorFlow 中应显式使用 `tensorflow::TensorShapeBase` 类型。 2. **不匹配的库文件** 检查是否已将正确的 `.lib` 文件添加至项目属性中的“附加依赖项”。具体路径如下: ``` ..\tensorflow\tensorflow\contrib\cmake\build\Release\tensorflow.lib ``` 3. **架构一致性** 确认所选的目标平台(x86/x64)与编译后的库文件一致。混用不同架构可能导致符号解析失败。 4. **C++ 标准兼容性** 更新项目选项以匹配 TensorFlow 所需的语言标准(通常是 C++17)。此设置可通过修改 Visual Studio 属性页完成。 --- #### 示例代码片段 以下展示如何初始化一个简单的 TensorFlow Session 对象: ```cpp #include "tensorflow/cc/client/client_session.h" #include "tensorflow/core/framework/tensor.h" using namespace tensorflow; int main() { Scope root = Scope::NewRootScope(); auto a = ops::Const(root.WithOpName("a"), {1, 2}); auto b = ops::Add(root.WithOpName("b"), a, a); ClientSession session(root); std::vector<Tensor> outputs; TF_CHECK_OK(session.Run({b}, &outputs)); LOG(INFO) << outputs[0].DebugString(); return 0; } ``` 上述代码展示了基本的操作符绑定逻辑以及客户端会话管理方式[^4]。 --- #### 注意事项 - 若尝试直接从互联网下载第三方提供的 `tensorflow_cc.dll`,务必验证其来源合法性及安全性。 - 自动化脚本可简化重复性的编译工作流;推荐学习 PowerShell 或 Bash 命令行技巧来提高效率。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值