C++ Runtime Code Reload

Windows下VS Code集成googletest:C++单元测试完整配置指南 单元测试是软件工程中验证代码逻辑正确性的基础实践,通过隔离测试单个函数或模块,确保代码质量与可维护性。其核心原理在于构建自动化测试套件,模拟各种输入条件并验证输出是否符合预期。在C++开发领域,googletest作为Google开源的事实标准框架,提供了丰富的断言机制、测试夹具和参数化测试功能,与CMake构建系统深度集成,成为工程实践的首选。对于Windows平台的开发者,尤其是在轻量级编辑器VS Code中配置C++测试环境,常面临工具链选择、构建配置和调试集成等挑战。本文针对这一场景,详细解析如何基 阅读详情

Quick prototyping and fast iteration times are incredibly important concepts for modern game development. Being able to hot swap an asset while the game is up and running can make the difference between a succesfull or a mediocre game simply because artists and designers can spend more time improving the game rather then waiting for loading/building/conditioning. The same benefit can be extended to code production by allowing to reload the source code while the application is still running and in this tutorial we will see how.

From an implementation point of view the only way to load code dynamically into a running application is via dynamic linking, and in Windows this means using DLLs. DLLs can be loaded into your program in two different ways, an implicit way, which is really similar to how you would link a normal lib file, or an explicit way. This second option is the key to make the runtime code reload component that we will see in this tutorial.

From an architectural point of view there are a few ways to make the code aware of the newly provided functions without having to change it. One way is to hijack the virtual table mechanism to make your function call jump at the new code when this is loaded, but this solution would require some level of symbol extraction (to locate the virtual table) and would also restrict an important language feature (polymorphism).
Another way, which is the one I have decided to present in this tutorial, is to use C++ macros to wrap our method and function definitions and expand the macro in different ways depending whether we are compiling the code to reload, or compiling the code that uses the reloadable module, or even building the release version of both which we probably don’t want to have any code reload support at all.

The overall idea will be to have the reloadable code compiled into a DLL, and the static code, including our c++ runtime reload module, compiled into the executable. When we trigger the code reload the runtime reload module will recompile the DLL, unload the current one and link the new one in. We will also organize the code so that all the functions get patched behind the scenes and the new memory locations are injected in place of the old ones. The build process will be implemented using MSBuild. The Visual Studio solution will have three projects, one for the Runtime Code Reload component, one for the reloadable code (the DLL) and one that is the UnitTest or the target application. The Runtime Code Reload will compile to a LIB, so in a more realistic case you would only have the target application and the DLL while linking against the RCR component.

Let’s start from seeing how to compile the DLL and how to use explicit linking to load it in.

DLL and explicit linking

The key mechanism that we will use is the explicit linking of the DLL. This means that the executable we will build will actually miss some of the function calls and we will need to provide the code for those functions before being able to invoke them. To load a DLL from disk we will use the Windows’ function LoadLibrary that, if succesfull, will return a HINSTANCE* that allows us to comunicate with the DLL. The other important function that we’ll use is GetProcAddress which takes a symbol name and a DLL HINSTANCE and returns a memory address. So if we want to find where the function foobar is we just call GetProcAddress(hDLL, “foobar”) and we will receive the address of that function. If we have succesfully received an address all we need to do is to cast it to a function pointer and we are finally able to call it. The annoying thing of all this process is that we are forced to use function/method pointers to invoke our code, and this is not good enough for what we want. We need to create a system that hides as much as possible all this mechanism. To do so we will use a few macros tricks.
These macros expand differently depending what defines are set:

#ifdef RCR_DLL_EXPORTS
// MACROS EXPANSION FOR THE DLL - These are the same whether RCR is enabled or not
#else // RCR_DLL_EXPORTS
#ifdef RCR_ENABLED
// MACROS EXPANSION FOR THE EXECUTABLE - When RCR is enabled
#else // RCR_ENABLED
// MACROS EXPANSION FOR THE EXECUTABLE - When RCR is disabled, for example in RELEASE
#endif // RCR_ENABLED
#endif // RCR_DLL_EXPORTS

As a first step we create a new Visual Studio project which in the provided code is named UnitTest_RCR_DLL. The target output of this project must be a dll and the compiler should define RCR_DLL_EXPORTS. The project will contain a dllmain.cpp for loading and unloading the resources when the DLL is linked, and two files (header and source) called UnitTest_RCR_DLL. The header file for UnitTest_RCR_DLL will be shared with the static/non reloadable executable, so this is where we use the polymorphic macros. To define a function we use the following code:

RCR_FUNCTION(int, testFunction1, (int a, float b), (a,b));

Which in this project will expand to:

int testFunction1(int a, float b);

The RCR_FUNCTION macro is defined to behave differently whether we are building the DLL or the executable; for the DLL it will expand as follows:

#ifdef RCR_DLL_EXPORTS
#define RCR_FUNCTION( returnType, name, args, vals ) __declspec(dllexport) returnType name args
#else // RCR_DLL_EXPORTS
...

Pretty simple, all we are doing is decorating the function with the export flag and then defining the function. In the CPP equivalent we have the function itself decorated with the RCR_API macro:

RCR_API int testFunction1(int a, float b)
{
    return (int)(a + b);
}

The RCR_API macro simply expands to __declspec(dllexport) if we are building the DLL.

This is all we need on the DLL side. With these few lines we have declared a function, exposed it to the DLL’s interface, and provided some implementation. Please note that the provided code has two additional files called UnitTest_RCR_DLL_1.cpp and UnitTest_RCR_DLL_2.cpp which get copied onto UnitTest_RCR_DLL.cpp during the UnitTest execution; obviously this is to demostrate the code reload feature!

User Code - The unit test

In our simple case the user code will be the actual unit test. There is only one relevant file stored into the UnitTest project and it’s called UnitTest.cpp. This file is represnet the user code, so this is where the RCR_ENABLED flag will be defined if the code is in Debug, and not defined in Release. Release will also need to link to the DLL in the project proprieties since the whole reload mechanism won’t be there. Let’s see the code.

#include <tchar.h>
#include <iostream>

#include "../UnitTest_RCR_DLL/UnitTest_RCR_DLL.h"

#ifdef RCR_ENABLED
#define RCR_DLL_NAME UnitTestRCRDLL
#include "../RuntimeCodeReload/RuntimeCodeReloader.h"
RCR_DEFINE_EXTERNALS
#endif

#define UNIT_TEST_ASSERT(a, mex) if(!(a)){ std::cout << "[!]\t"<< mex << " failed." << std::endl; testPassed = false; }else{ std::cout << "\t" << mex << " passed." << std::endl; }

int _tmain(int, _TCHAR*[])

The #ifdef RCR_ENABLED code is used to define the DLL name for the Runtime Code Reloader. This is because that name is hardwired into some of the variables so it needs to be defined just before the include. The other important line is the RCR_DEFINE_EXTERNALS macro. This will expand into two variables, an HINSTANCE for the DLL and a std::map called RCR_SYMBOL_MAP:

// From RCR.h
#define RCR_DLL_HISTANCE RCR_CONCAT(g_hGetProcIDDLL_,RCR_DLL_NAME)
#define RCR_SYMBOL_MAP RCR_CONCAT(g_symbolMap_,RCR_DLL_NAME)

extern HINSTANCE RCR_DLL_HISTANCE;
extern std::map<std::string, std::string> RCR_SYMBOL_MAP;
#define RCR_DEFINE_EXTERNALS HINSTANCE RCR_DLL_HISTANCE; std::map<std::string, std::string> RCR_SYMBOL_MAP;

These two global variables are used to access into the DLL. Now let’s take a look at the main function:

int _tmain(int, _TCHAR*[])
{
    using namespace UnitTest_RCR;
    bool testPassed = true;

    std::cout << "[RCR Unit Test]" << std::endl;

#ifdef RCR_ENABLED
    auto attributes = GetFileAttributesA("..\\UnitTest_RCR_DLL\\UnitTest_RCR_DLL.cpp");
    SetFileAttributesA("..\\UnitTest_RCR_DLL\\UnitTest_RCR_DLL.cpp", FILE_ATTRIBUTE_NORMAL);
    CopyFileA("..\\UnitTest_RCR_DLL\\UnitTest_RCR_DLL_1.cpp", "..\\UnitTest_RCR_DLL\\UnitTest_RCR_DLL.cpp", false);
    SetFileAttributesA("..\\UnitTest_RCR_DLL\\UnitTest_RCR_DLL.cpp", attributes);
    std::cout << "\tCompiling DLL..." << std::endl;
    std::vector<std::string> configurations;
    configurations.push_back("Debug");

    // !! ------------------------------------------------------------------------------------------------------------------------
    //    YOU WILL NEED TO REPLACE THE <<vcvarsall>> PATH TO POINT TO THE CORRECT FOLDER ON YOUR PC
    // !! ------------------------------------------------------------------------------------------------------------------------
    RCR::RuntimeCodeReloader codeReloader(&RCR_DLL_HISTANCE, &RCR_SYMBOL_MAP, "C:\\Program Files (x86)\\Microsoft Visual Studio 10.0\\VC\\vcvarsall.bat","..\\RuntimeCodeReload.sln", "..\\bin\\UnitTest_RCR_DLL_d.dll",  "C:\\temp\\UnitTest_RCR_DLL_d\\", "UnitTest_RCR_DLL", configurations );
    std::cout << "\tDone..." << std::endl << std::endl;
#endif

    TemplateStruct<float> paramTemplateStruct;
    paramTemplateStruct.value = 2.0f;

    UNIT_TEST_ASSERT( testFunction1(10, 8.0f) == 80, "testFunction1 code test ");
    UNIT_TEST_ASSERT( testFunction2(&paramTemplateStruct) == 4.0f, "testFunction2 code test ");

    GET_RCR_VARIABLE_PTR(size_t, UnitTest_RCR:: , g_globalValue);
    UNIT_TEST_ASSERT( *g_globalValue == 90, "g_globalValue default test ");
    testFunction3( 23 );
    UNIT_TEST_ASSERT( *g_globalValue == 23, "g_globalValue change test ");

    UNIT_TEST_ASSERT( testFunction4("AB") == 'A', "testFunction4 code test ");
    {
        TestClass testObj(12,30);
        UNIT_TEST_ASSERT( testObj.test(5) == 12 + 30 * 5, "object method invocation test ");
    }

#ifdef RCR_ENABLED
    std::cout << std::endl << "\tModifing source code..." << std::endl;
    attributes = GetFileAttributesA("..\\UnitTest_RCR_DLL\\UnitTest_RCR_DLL.cpp");
    SetFileAttributesA("..\\UnitTest_RCR_DLL\\UnitTest_RCR_DLL.cpp", FILE_ATTRIBUTE_NORMAL);
    CopyFileA("..\\UnitTest_RCR_DLL\\UnitTest_RCR_DLL_2.cpp", "..\\UnitTest_RCR_DLL\\UnitTest_RCR_DLL.cpp", false);
    SetFileAttributesA("..\\UnitTest_RCR_DLL\\UnitTest_RCR_DLL.cpp", attributes);
    std::cout << "\tRecompiling DLL..." << std::endl;
    codeReloader.reload(RCR::RuntimeCodeReloader::eCleanCompileAndReload);
    std::cout << "\tDone..." << std::endl << std::endl;

    UNIT_TEST_ASSERT( testFunction1(10, 8.0f) == 18, "testFunction1 code test ");
    UNIT_TEST_ASSERT( testFunction2(&paramTemplateStruct) == 1.0f, "testFunction2 code test ");
    UNIT_TEST_ASSERT( *g_globalValue == 13, "g_globalValue default test ");
    testFunction3( 20 );
    UNIT_TEST_ASSERT( *g_globalValue == 10, "g_globalValue change test ");
    UNIT_TEST_ASSERT( testFunction4("AB") == 'B', "testFunction4 code test ");

    {
        TestClass testObj(12,30);
        UNIT_TEST_ASSERT( testObj.test(5) == 12 + 30 / 5, "object method invocation test ");
    }
    CopyFileA("..\\UnitTest_RCR_DLL\\UnitTest_RCR_DLL_1.cpp", "..\\UnitTest_RCR_DLL\\UnitTest_RCR_DLL.cpp", false);
#endif

    if(testPassed)
        std::cout << "[PASSED]" << std::endl;
    else
        std::cout << "[FAILED]" << std::endl;

    return 0;
}

Take your time to read through the code; the highlighted bits are where the code reload features kick in. The CopyA call is to simulate that the file “…\UnitTest_RCR_DLL\UnitTest_RCR_DLL.cpp” has changed, in the real case you probably want to have a directory watcher on your source code folder, and when a file changes you can call the reload function.

This is all you need to use the library. If you are interested in finding out how it works behind the scene, then keep on reading.

Runtime loading of the DLL

The Runtime Code Reload component is the library that offers the reload functionality and it’s composed of two main header files: RuntimeCodeReloader.h and RCR.h. The first file offers a class that can be used by the user’s source code to trigger a reload, and its interface looks like this:

class RuntimeCodeReloader
{
public:
    enum Flag
    {
        eCleanCompileAndReload,
        eCleanCompileAndNoReload,
        eCompileAndReload,
        eCompileNoReload,
        eNoCompileAndReload,
    };

    // Ctor/Dtor
    // ------------------------------------------------------------------------
    RuntimeCodeReloader(HINSTANCE* hDLLInstance, std::map<std::string, std::string>* dllSymbolMap, const char* vcvarsallPath, const char* solutionFullPath, const char* dllFullPath, const char* dllTemporaryDir, const char* projectName, std::vector<std::string> &configurations);
    ~RuntimeCodeReloader();

    // Methods
    // ------------------------------------------------------------------------
    bool reload(Flag flag = eCompileAndReload);
    ...

In the user code we will construct one of these objects providing the relevant parameters. The first two are globally defined in the RCR.h file and we’ll see them in a moment, while the rest of the parameters are all paths to different places that we need. VcvarsallPath is the path to the vcvarsall.bat batch file in the Visual Studio directory, something like “C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat”. SolutionFullPath and dllFullPath in the tutorial’s layout are “…\RuntimeCodeReload.sln” and “…\bin\UnitTest_RCR_DLL_d.dll”. dllTemporaryDir is where our compiled output is going to be stored during the reload, and it must be an absolute path because it’s used by two different processes during the reload and the relative path would be different for each. Project name is the Visual Studio project name for the DLL project in our solution (“UnitTest_RCR_DLL”) and configurations is a vector of strings that specify which configurations to build (in our case “Debug” and nothing else).

The other function exposed is called reload and is the function to call to trigger the code reload. The input flag should be pretty self explanatory. The CPP code of this is the following:

bool RuntimeCodeReloader::reload(Flag flag)
{
    bool needCompiling = flag == eCleanCompileAndReload || flag == eCleanCompileAndNoReload || flag == eCompileAndReload || flag == eCompileNoReload;
    bool needReloading = flag == eCleanCompileAndReload || flag == eCompileAndReload || flag == eNoCompileAndReload;

    if(needCompiling)
    {
        if( !compileDLL(flag) )
            MessageBoxA(0, "Failed to compile the required DLL; check that all the paths are correct and retry.", "Runtime Code Reload - ASSERT", MB_ICONERROR);
    }

    if(needReloading)
    {
        // Release the DLL
        if(m_hGetProcIDDLL)
        {
            FreeLibrary(*m_hGetProcIDDLL);
            *m_hGetProcIDDLL = 0;
        }

        // The new DLL is created in a temporary folder; retrieve the DLL and copy it to the right place
        bool result = CopyFile( (std::string(m_dllTemporaryDir) + '\\' + getFilename(m_dllFullPath) ).c_str(), m_dllFullPath, false) == TRUE;
        if(!result)
        {
            char auxString[256];
            sprintf_s(auxString, "Failed to copy the DLL from %s to %s", (std::string(m_dllTemporaryDir) + '\\' + getFilename(m_dllFullPath) ).c_str(), m_dllFullPath);
            MessageBoxA(0, auxString, "Runtime Code Reload - ASSERT", MB_ICONERROR);
        }
        // Copy all the files from the directory; this will copy the DLL again, useless but won't fix for now
        CopyAllFiles(m_dllTemporaryDir, getDirectories(m_dllFullPath).c_str());
        DeleteAllFiles(m_dllTemporaryDir);
        RemoveDirectory(m_dllTemporaryDir);

        // Even if we filed we try to load it, we may just have failed to compile due to code issues but the old dll is actually there
        *m_hGetProcIDDLL = LoadLibraryA(m_dllFullPath);

        if (!*m_hGetProcIDDLL)
        {
            RCR_ASSERT(false, "Failed to load the required DLL; check that the DLL's path is correct and retry.");
            return false;
        }

        *m_dllSymbolMap = createDLLExportedSymbolsConversionTable(m_dllFullPath);
    }
        
    return true;
}

If the flag requires the DLL to be compiled, then compileDLL is called. If reloading is needed then the code release the current DLL, copies the new one from the temporary folder to the path we specified during construction. If the copy failes an error is popped, otherwise the whole folder is copied across; this is mainly to take in the PDB file and avoid losing symbols. Once the DLL is in place we call LoadLibrary to link it in. The last function call createDLLExportedSymbolsConversionTable is used by the code to create a map between the DLL internal naming convention and the more C++ like naming convention we are used to. The reason for this is that when we will try to call a function we’ll need to search for it into the DLL, so we will need to adhere to the DLL naming convention, but the name we will provide is going to C++ like, so we need a map between the two.

The compileDLL function is quite simple, so I am not going to cover it here. The more tricky bit that may be difficult to unravel is the RCR.h file. This is where all the magic happens and being heavily macro based it’s hard to read. Let’s analyze how it works for a simple function. The RCR_FUNCTION macro that we have seen before expands differently in the user code since it will need to search the function into the DLL and then call it.

#define RCR_FUNCTION( returnType, name, args, vals )\
static returnType name args { \
    typedef returnType (*name##_type) args; \
    GET_RCR_FUNCTION(func, name##_type, RCR_findSymbol(RCR_MAKE_STRING(returnType), RCR_CONCAT(RCR_CURRENT_NAMESPACE_SEQUENCE,RCR_MAKE_STRING(name)),RCR_MAKE_STRING(args))); \
    return func##vals;\
}

The macro defines a static function, then a typedef that is a pointer to that function type and then it creates a function pointer of that function type called func. Eventually it invoke func with the correct arguments and return the value.
Of this macro the important bit is the GET_RCR_FUNCTION macro, which expands as follow:

#define GET_RCR_FUNCTION(functionName, functionType, sym) functionType functionName = (functionType)GetProcAddress(RCR_DLL_HISTANCE, sym);

So, given a dll symbol name and the RCR_DLL_HINSTANCE the code (finally!) calls the GetProcAddress to find where the function lives in memory. The symbol sym is in the DLL mangled name convetion which we obtain from the previous macro from:

.. RCR_findSymbol(RCR_MAKE_STRING(returnType), RCR_CONCAT(RCR_CURRENT_NAMESPACE_SEQUENCE,RCR_MAKE_STRING(name)),RCR_MAKE_STRING(args)) ..

RCR_findSymbol is a function that looks up into the map and transform the name extracted from the macros to the DLL mangled equivalent. RCR_CURRENT_NAMESPACE_SEQUENCE is a nasty hack I couldn’t find any way around; to match the name we need the namespace we are in, but there is no way to get the namespace name from the function definition, so the user will need to define this macro every time it modifies the namespace sequence. This can be seen in the UnitTest_RCR_DLL file:

namespace UnitTest_RCR
{
    #undef RCR_CURRENT_NAMESPACE_SEQUENCE
    #define RCR_CURRENT_NAMESPACE_SEQUENCE "UnitTest_RCR::"
    ...
    RCR_FUNCTION(int, testFunction1, (int a, float b), (a,b));

Ugly but necessary. The code will create our function symbol string, which in the testFunction1 case would be “int UnitTest_RCR::testFunction1(int,float)”, then run it through RCR_findSymbol to get the DLL equivalent ("?testFunction1@UnitTest_RCR@@YAHHM@Z").

Variables and methods follow the same principle, so feel free to check the RCR.h code file to see the details.

Visual Studio 2010 project file and source code is provided, Download sources

llama.cpp CPU推理实战:C/C++轻量化部署GGUF大模型 大语言模型推理不再依赖GPU和Python生态,CPU端原生推理正成为边缘计算与终端AI的关键路径。其核心在于将模型压缩、内存映射与硬件指令级优化深度耦合——GGUF格式实现零拷贝内存加载,C/C++提供确定性低延迟执行,量化策略(如Q4_K_M、Q5_K_M)平衡精度与吞吐,而CMake则作为跨平台硬件特性的编译时开关矩阵。这种技术组合显著降低部署门槛,支持在MacBook Air、树莓派、NAS甚至无显卡Windows设备上本地运行3B~7B级模型,广泛应用于私有知识库、离线助手、嵌入式AI交互等场景。 阅读详情

相关推荐

4B模型本地自动化编码实战:GGUF+llama.cpp+LM Studio全栈指南

轻量级大语言模型(如4B参数级)正成为边缘设备与离线环境实现自动化编码的关键技术基础。其核心原理在于通过GGUF格式实现低内存占用与原生量化支持,结合llama.cpp的CPU/GPU协同推理优化,达成高吞吐、低延迟的代码生成能力。该技术路径显著降低AI编程门槛,具备无需GPU、兼容主流开发工具、支持树莓派等嵌入式平台等工程优势,广泛适用于企业内网开发、硬件原型设计及编程教学等场景。本文聚焦Qwen2.5-4B等典型4B模型在LM Studio平台上的端到端部署与调优实践。

weixin_33862993的博客 834

C++覆盖、重载、多态区别 ; 重载、重写(覆盖)、重定义(隐藏)三者区别

覆盖: 在基类中定义了一个非虚拟函数,然后在派生类中又定义了一个同名同参数同返回类型的函数,这就是覆盖了。 在派生类对象上直接调用这个函数名,只会调用派生类中的那个。 //coverage.cpp   #include using namespace std;   class A { public:   void ShowMessage(

SYP35的专栏 564

C++ RESTful服务实战:从环境搭建到Nginx部署完整指南

在现代软件开发中,构建高性能、可扩展的网络服务是核心需求。RESTful架构作为一种基于HTTP协议的软件架构风格,通过标准化的资源操作方式(如GET、POST、PUT、DELETE)和轻量的JSON数据格式,成为构建Web API的主流选择。其技术价值在于提供了清晰、无状态、可缓存的接口设计范式,极大提升了系统的可维护性和跨平台兼容性。在C++工程实践中,结合轻量级HTTP库(如cpp-httplib)和JSON处理库,开发者能够构建出媲美动态语言的高性能后端服务。应用场景广泛,从微服务架构中的独立模块到

weixin_30340819的博客 313

python中reload(module)的用法

1、Python2中可以和Python3中关于reload()用法的区别。 Python2 中可以直接使用reload(module)重载模块。 Pyhton3中需要使用如下方式: (1) >>> from imp >>> imp.reload(module)(2) >>> from imp import reload >>> reload(module)     2、Python3中

xl365t 1万+

C++构建生产级REST API:Nginx反向代理架构实战指南

在构建高性能网络服务时,反向代理是一种核心的架构模式,它通过将客户端请求转发给后端应用服务器,实现了负载均衡、安全防护和静态资源服务等功能。Nginx作为高性能的HTTP服务器和反向代理,采用事件驱动、异步非阻塞模型,能轻松处理高并发连接,是构建可扩展、稳定Web服务的基石。结合C++的高性能计算能力,可以打造出兼顾性能与工程实践的解决方案。这种架构模式特别适用于需要对外提供HTTP接口的C++后台服务场景,通过让Nginx负责网络层面的繁重工作,而C++程序专注于核心业务逻辑,实现了专业工具做专业事的分工

weixin_30634661的博客 315

ModuleHotReload:C ++模块类热重装,可按需重新编译

ModuleHotReload 具有按需重新编译的C ++模块/类热重载。

页面刷新的reload()和refresh()方法有什么不同

window.reload是重新加载当前需要的所有内容,也就包括页面和后台的代码,此过程中实际上是从后台重新进行操作;window.Refresh是刷新,保留之前的缓存内容,重新加载页面,之前存在的东西不会动,没加载上来的东西继续加载,也会去加载后台代码内容的。

kakaxiD的博客 3万+

CSP-J 初赛模拟卷1 题解

只有一棵子树有后继,其他的都是叶结点才能保证树的深度最大,此时还剩(n-5)个结点,最后加上2,得到(n-3),即为答案。题解:先修改p的指针域,让它的左指针域指向q,然后再让q的右指针域赋值给p的右指针域,再然后修改q的右指针域使其指向p,最后需要改变的指针域就是原先q结点的后继节点的左指针域内容。设n个元素的入栈序列是1,2,3,...,n,出栈序列为p1,p2,...,pn,若p1=n,则pi(1≤i≤n)的值为(1)输入的三个数中,第二个数应是[0,11]上的整数,否则会出现数组越界的问题。

Sat77GryHp_Pro的博客 2805

Compose Hot Reload 为什么只支持桌面 JVM,它和 Live Edit 又有什么区别?

所以可以看到,虽然都是 JVM 体系,但是对于 Compose 来说,Desktop 和 Android 在 Hot Reload 的实质支持上其实并不通用,另外 iOS 就更不用说了,基于 Kotlin/Native 和 iOS 平台的设计,要在其上做开发过程的二进制 Hot Reload 无疑更加困难,比如iOS 26 封禁 mprotect 之后,Flutter 在 iOS 26 的 debug Hot Reload 也需要添加解释执行来适配。

恋猫de小郭的博客 1147

OpenBCI脑电帽硬件DIY与低成本搭建实战

本文详细介绍了如何通过第三方兼容硬件和开源设计,低成本DIY一套功能完备的OpenBCI脑电采集系统。从硬件选购、组装、软件配置到信号调试,提供了完整的实战指南,将总成本控制在千元级别,使脑机接口技术对爱好者、学生和研究者变得更加触手可及。

weixin_29322855的博客 786

ESXI 8.0.3 ubuntu 24.04 直通显卡P40

手把手,一步步教你直通GPU,ESXI 8.0.3 ubuntu 24.04 直通显卡P40

qq_36433118的博客 4682

llama.cpp:轻量跨平台AI模型本地部署的务实之选

AI本地模型部署的核心挑战在于平衡资源消耗、运行效率与工程确定性。传统Python推理框架虽生态丰富,却因解释器开销、CUDA依赖和内存管理冗余,难以满足低配设备、嵌入式终端及企业内网等真实场景需求。llama.cpp通过纯C/C++重写推理引擎,将模型加载、量化计算与KV缓存完全下沉至系统层,实现无Python、无CUDA、无Docker的极简部署。其GGUF格式统一了模型分发标准,OpenMP后端保障CPU高效利用,Q6_K等量化策略兼顾精度与体积——这正是‘本地好用的ai模型’落地的关键技术路径。本文

weixin_34199335的博客 372

Isaac Lab 强化学习全身控制策略 Sim2Real 宇树人形机器人训练部署 HOVER

《IsaacLab策略训练与部署指南》提供了在仿真和真实机器人上实现HOVER全身控制策略的完整流程。主要内容包括:1) Linux环境下的IsaacLab安装与HOVER资源库配置;2) 使用1024个并行环境训练教师/学生策略的详细步骤;3) 策略测试与评估方法;4) Sim2Sim仿真验证和Sim2Real真实机器人部署方案。本教程特别针对Unitree H1仿人机器人,包含运动数据准备、策略训练、性能评估到硬件部署的全链条实现方案,为机器人控制策略开发提供标准化参考框架。

机器人控制与仿真应用 3069

5 分钟搭好你自己的本地 OpenAI:llama.cpp llama-server 本地 LLM 推理服务实战

llama.cpp 是一个纯 C/C++ 的 LLM 推理引擎,而 `llama-server` 就是它内置的本地推理 HTTP 服务:把一个 GGUF 模型丢给它,就能获得一套 OpenAI 兼容 API、多用户并行解码和开箱即用的 Web UI。如果你的目标是 llama-server 部署、本地推理服务配置与 GGUF 模型本地部署,不需要维护额外的 Python 推理栈,构建、启动到完成第

gitblog_02983的博客 486

【100分- 求最多可以派出多少支团队】(题目+思路+Java&C++&Python解析+在线测试)

用数组代表每个人的能力,一个比赛活动要求参赛团队的最低能力值为N,每个团队可以由1人或者2人组成,且1个人只能参加1个团队,计算出最多可以派出多少只符合要求的团队。

m0_73659489的博客 313

Docker(八):Docker Compose(容器编排) 管理多容器应用—实战案例演示

🟢 Docker(八):Docker Compose(容器编排) 管理多容器应用—实战案例演示

✨ 欢迎来到【Seal ^_^ 的优快云博客】!✨ 6万+

llama.cpp llama-server 完全指南:三步部署本地 OpenAI 兼容推理服务

llama-server 是 llama.cpp 内置的纯 C/C++ HTTP 推理服务器,它把本地模型的推理能力封装成一套 REST API——其中包含 OpenAI 与 Anthropic 兼容端点——并附带一个开箱即用的 Web UI。没有 Python 运行时依赖,服务器核心就是一个 [httplib](https://link.gitcode.com/i/29846dcdcf56ce8

gitblog_00960的博客 243

(王道计算机组成原理)第二章数据的表示和运算-第三节:运算方法和运算电路 1(基本运算部件)

本文主要介绍了计算机组成原理中的加法器和算术逻辑单元(ALU)的基本概念与实现原理。首先,文章详细讲解了一位全加器的工作原理,包括其输入输出、逻辑表达式及真值表。接着,介绍了并行加法器的两种类型:串行进位和并行进位的加法器,分析了它们的优缺点。随后,文章探讨了带标志位的加法器,说明了如何通过标志位生成逻辑来判断加法结果的状态。最后,文章阐述了ALU的功能及其实现原理,包括ALU的基本结构、控制信号的作用以及在实际考试中的图示表示。通过这些内容,读者可以全面了解加法器和ALU在计算机中的重要作用及其工作原理。

快乐江湖的博客 3837

llama.cpp llama-server 部署实战:从 0 到本地 OpenAI 接口的完整落地指南

如果你的目标是把 llama.cpp 的 `llama-server` 部署起来、拿到一套 OpenAI 兼容 API 并让现有应用零改造地指过来,这篇文章按"跑通 → 接入 → 调优 → 运维"的真实操作动线走一遍。全程不需要维护任何 Python 推理栈,构建、启动、调参、排错的关键数字与开关名都标在文中。 ## 一个二进制、一组 OpenAI 兼容接口:llama-server 到底干什么

gitblog_00339的博客 126

Android Studio无法启动,Failed to create JVM:error code -1. JVM Path 完美解决方案

Android Studio无法启动,Failed to create JVM:error code -1. JVM Path 完美解决方案。 找到Android studio的启动文件bin目录,把studio64.exe.vmoptions 删除或改名(推荐改名,方便恢复),如果你是32位系统这个文件就是 studio.exe.vmoptions

陈万洲的专栏 4849

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

微信聊天记录完整实操:如何免费导出十年对话并生成自己的年度聊天报告

导出的 HTML 文件第一次在浏览器里打开时,我看到三年前以为弄丢的那个群,图片一张不少。那一刻我确认:微信聊天记录导出这件事,自己在家就能做成,前后大概十分钟。我用的是开源项目留痕(WeChatMsg),它读取本地微信记录,能导出成 HTML、Word、CSV 永久保存,还能基于这些记录生成年度聊天报告。下面是我实际走过的路。 ## 微信备份和聊天记录导出差在哪 我原来一直觉得"备份"就够了

gitblog_00063的博客 326

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

llama.cpp llama-server 实战指南:用 OpenAI 兼容 API 快速搭建本地 LLM 推理服务

llama.cpp 的 llama-server 能把一个 GGUF 模型变成带 OpenAI 兼容 API 的本地 LLM 推理服务:纯 C/C++ 实现,无 Python 依赖,同一 URL 自带 Web UI。本文面向第一次部署本地推理服务的开发者。 ## 什么时候部署 llama-server:五个场景与一个雷区 - **内网私有问答**:数据不出网,`--api-key` 一开就能接

gitblog_00974的博客 400

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

用Node.js对接国产大模型实现Claude Code体验

Claude Code并非可安装的桌面应用,而是一种基于大模型的代码补全能力封装;其核心原理是通过标准化API协议(如OpenAI兼容接口)桥接本地开发环境与后端推理服务。技术价值在于摆脱海外API依赖、满足信创合规要求,并支持模型热切换与私有化部署。典型应用场景包括政企内网AI编程辅助、工业质检SaaS中的离线代码生成,以及国产GPU(昇腾/寒武纪/飞腾)上的轻量化模型推理。本文聚焦Node.js作为协议翻译与服务编排中枢,详解架构测绘、API协议适配、VSCode插件桥接及ONNX Runtime国产化

weixin_30902251的博客 353

如何 5 分钟搭好本地 OpenAI 兼容接口:llama.cpp llama-server 本地推理服务完整指南

llama.cpp 是纯 C/C++ 编写的 LLM 推理引擎,llama-server 就是它自带的本地 LLM 推理 HTTP 服务:把一个 GGUF 模型文件交给它,即得到一套 OpenAI 兼容 API、多用户并行解码能力,以及打开浏览器就能用的 Web UI。全程零 Python 运行时依赖,单二进制放到哪台机器上服务就能跑在哪里,这对嵌入式 ARM 设备、老服务器和最小容器镜像尤其友好

gitblog_01030的博客 340

llama.cpp llama-server 本地推理服务指南:从 GGUF 模型到 OpenAI 兼容接口的部署全流程

llama-server 是 llama.cpp(一个纯 C/C++ 的 LLM 推理引擎)内置的本地推理服务:它把 GGUF 模型封装成一套 OpenAI 兼容接口外加 Web UI,二进制本身不依赖任何 Python 运行时,构建完成到发出第一条 API 请求大约只要 5 分钟。本文按你实际会遇到的问题推进——为什么用它替代云端 API、机器上怎么跑起来、现有客户端怎么接、多人共用怎么调、出问

gitblog_00506的博客 203
上一篇: https的中间人攻击和防范
下一篇: IsBadReadPtr函数和异常处理
CoderAldrich
博客等级 码龄12年 431粉丝 24原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值