SWIG和MapGuide Web API

利用gsoap在C/C++实现httpclient功能 同时与webservice webapi通信 声明:本文使用gsoap只用于客户端接口调用,不用于服务端开发,服务端接口在vs2017开发,部署在iis上。 gsoap可以与webservice通信,也可以与web api通信。这样在在c++代码中只要gsoap这一个库就可以了。 gsoap工具一般是用于webservice接口的调用,而使用httpget,httppost方式调用web api则属于gsoap额外的功能,需要另外添加文件... 阅读详情

    许多人都知道MapGuide提供了.NET、PHP和Java三种类型的Web API,但是不知道MapGuide是如何创建这三种类型的API的。试想一下,如果分别去创建这三种API,这将是一个很难维护的工作。每次增加或修改一些功能,就需要对三种类型的API都进行修改。所以,MapGuide使用了SWIG来自动生成这三种类型的API。我想这个时候许多人会问,什么是SWIG呢?我怎么从来没有听说过这个东东呢!其实,我也是在做MapGuide开发的时候才开始了解SWIG的。所以,首先让我们来认识一下SWIG,然后再来看MapGuide是如何使用SWIG来生成API的。

 

1. SWIG简介

    SWIG是Simple Wrapper and Interface Generator的缩写,是一个帮助使用C或者C++编写的软件创建其他编语言的API的工具。例如,我想要为一个C++编写的程序创建.NET API,一般情况下我必须使用托管C++(Managed C++)去编写大量的代码才能生成它的.NET API。有了SWIG,这个机械的工作将变得非常简单。你只须要使用一个接口文件告诉SWIG要为那些类创建.NET API,SWIG就会自动帮你生成它的.NET API。是不是非常的酷啊?

    当然,SWIG不仅仅支持创建.NET API。最新版本的SWIG支持常用脚本语言Perl、PHP、Python、Tcl、Ruby和非脚本语言C#, Common Lisp (CLISP, Allegro CL, CFFI, UFFI), Java, Modula-3, OCAML以及R,甚至是编译器或者汇编的计划应用(Guile, MzScheme, Chicken)。

    下面我们通过一个例子来看看SWIG是如何帮我们创建API的。假设我打算为如下的C++类创建C#和Java的API。

    /* SwigTest.h */

    class CSwigTest {
    public:
        CSwigTest();
        virtual ~CSwigTest();
        int Add(int a, int b) { return a + b; }
        int Substract(int a, int b) { return a - b; }

        int Multiple(int a, int b) { return a * b; }
        float Divide(int a, int b) { return (float)a / (float)b; }
    };

 

1.1 接口文件

    首先,你需要写一个接口文件(Interface File),告诉SWIG要为那些类的那些方法创建API。如下的接口文件只为类CSwigTest的方法Add(...)和Subtract(...)生成API,因为在接口文件的接口声明部分只声明了两个方法。

    /* SwigTest.i */
    %module SwigTest
    %{
    #include "SwigTest.h"
    %}

    /* --- 接口声明部分 ---*/
    class CSwigTest {
    public:
        int Add(int a, int b);

        int Substract(int a, int b);

    };

 

    注解:%module标记用于定义SWIG生成的模块的名称,%{%}标记中的内容会被一字不差地插入SWIG自动生成的文件xxx_wrapper.c中,其中xxx代表用%module指定的模块名称。这个文件会在下面介绍,不必着急去理解它究竟有什么作用。

    如果打算为类中所有方法创建API,那么有一个非常简单的办法,在接口文件的类声明部分使用%include标记。SWIG将对%include所指定的文件进行语法分析,类中所有公有方法(Public Method)都将在API中暴露。

    /* SwigTest.i */
    %module SwigTest
    %{
    #include "SwigTest.h"
    %}
    #include “SwigTest.h” 

 

1.2 编译模块

    有了接口文件之后,剩下的事就是执行几条命令。下面我们以Windows平台上生成.NET API为例介绍这些命令。

    (a) 调用SWIG自动生成代码

    swig -csharp  SwigTest.i

    执行上面的命令会产生一个C语言文件SwigTest_wrapper.c和多个C#文件。在文件SwigTest_wrapper.c中,SWIG为接口文件中接口声明部分指定的每个方法产生一个全局方法,以便C#使用Pinvoke调用这些函数。而那些C#文件就是用来生成.NET API的。

    (b) 为C++代码生成DLL(动态链接库)

    cl SwigTest_wrapper.c *.cpp

    link *.obj /out:SwigTest.dll

    执行上面的命令,会为我们编写C++代码生成DLL。在编译C++文件时,一定要包括SWIG为我们生成的C++文件SwigTest_wrapper.cpp。

    注意:为了让大家便于理解上述命令,这些命令并没有列出完整的编译和链接选项。

    (C) 生成.NET模块

    csc /out:SwigTestNotNetAPI.dll /target:library *.cs

    执行上面的命令就生成了.NET API模块SwigTestNotNetAPI.dll。如果用户想使用这些API,只需要添加对SwigTestNotNetAPI.dll的引用(Reference)就可以了。

    生成其它语言类型API的命令基本类似,下面我们再以Java在Unix平台下的命令为例结束对SWIG的介绍。事实上,SWIG也是一个开源项目。如果想了解更多关于SWIG的信息,大家可以登陆SWIG的官方网站www.swig.org,那里有SWIG最详细的资料。
    $ swig -java SwigTest_wrapper.i
    $ gcc -c *.cpp SwigTest_wrapper.c -I/c/jdk1.3.1/include -I/c/jdk1.3.1/include/win32
    $ gcc -shared *.o -mno-cygwin -Wl,--add-stdcall-alias  -o SwigTest.dll

 

2. SWIG在MapGuide中的应用

    我们在前面已经提到过,MapGuide使用了SWIG来自动生成.NET、Java和PHP这三种类型的API。但是,SWIG也有不少限制和缺陷,所以MapGuide对SWIG源代码进行了大量的修改,以满足自己的要求。下面,我们看看这些改进。

2.1 IMake工具

    SWIG要求开发人员编写一个接口文件,那么能否让接口文件自动生成呢?借用一句中国移动的广告词,我能!虽然SWIG没有提供这方面的工具,但是我们可以自己开发吗!IMake(Interface Maker)就是为了满足这样的要求而开发一个工具,给定一个XML文件,它能帮你自动生成SWIG接口文件。登录MapGuide开源版的代码浏览页面(http://trac.osgeo.org/mapguide/browser),在root/trunk/MgDev/BuildTools/WebTools/IMake文件夹下可以找到IMake的源代码。

     下面我们以MapGuide中使用的XML文件/trunk/MgDev/Web/src/MapGuideApi/MapGuideApiGen.xml为例,介绍一下IMake的用法。为了便于理解,在此我删掉了文件中的部分内容。

    <?xml version="1.0" encoding="UTF-8"?>
    <Parameters>
      <!-- 对应于%Module标记. -->
      <Module name="MapGuideApi" />

 

      <!-- 生成的接口文件的名称. -->
      <Target path="./MapGuideApi.i" />

 

      <!-- 对应于%{%}标记 -->
      <CppInline>
        #include &lt;string&gt;
        #include &lt;map&gt;
        #include "MapGuideCommon.h"
        #include "WebApp.h"
        ......
      </CppInline>

 

      <!-- 用于替换接口中使用的部分类型 -->
      <TypeReplacements>
        <TypeReplacement oldtype="CREFSTRING" newtype="STRINGPARAM" />
        <TypeReplacement oldtype="INT64" newtype="long long" />
      </TypeReplacements>

 

      <!-- 此部分的内容添加在%{%}之后,接口声明部分之前 -->
      <SwigInline>
        %include "language.i"   //typemaps specific for each language
        ......
      </SwigInline>
     
      <!-- 为指定的C++文件生成接口声明 -->
      <Headers>
        <Header path="../../../Common/Foundation/Data/Property.h" />
        ......
      </Headers>
    </Parameters>

 

    执行命令“IMake MapGuideApiGen.xml”,IMake就帮我们自动生成了如下SWIG接口文件MapGuideApi.i。

    /* MapGuideApi.i */
    %module MapGuideApi
    %{
        #include <string>;
        #include <map>;
        #include "MapGuideCommon.h"
        #include "WebApp.h"
        ......
    %}
 
    %include "language.i"   //typemaps specific for each language
    ......

 

    class MgProperty: public MgNamedSerializable
    {
    public:
        virtual INT16 GetPropertyType();
        STRING GetName();
        void SetName(CREFSTRING name);
    };

    ......

 

    如果打开文件Proper.h,我们可以看到MgProperty有更多的方法,例如CanSetName(...)。为什么只有三个方法添加到了SWIG接口文件中?IMake在生成接口文件时,它会查找C++头文件中的宏PUBLISHED_API。只有被PUBLISHED_API修饰的方法,才会添加到接口文件中。

    注:宏PUBLISHED_API和INTERNAL_API的定义如下。

    #define PUBLISHED_API public

    #define INTERNAL_API public

 

    class MG_FOUNDATION_API MgProperty : public MgNamedSerializable
    {
    PUBLISHED_API:

        virtual INT16 GetPropertyType() = 0;  /// __get  
        STRING GetName();  /// __get, __set
        void SetName(CREFSTRING name);
 
    INTERNAL_API:
        virtual bool CanSetName();
 
    protected: 
        INT32 GetClassId();
        MgProperty();
        virtual ~MgProperty();
        virtual void Dispose();  
        virtual void ToXml(string &str, bool includeType = true, string rootElmName = "Property") = 0;
 
    private:
        friend class MgPropertyCollection;
        STRING m_propertyName;
 
    CLASS_ID:
        static const INT32 m_cls_id = Foundation_Property_Property;
    };     
    给定一个C++常量定义文件,IMake还可以自动生成对应的其他语言的常量定义文件。MapGuide .NET Web API中的所有常量都是使用IMake来生成的,例如MgMineType、MgPropertyType等。下面我们以MapGuide中使用的XML文件/trunk/MgDev/Web/src/MapGuideApi/Constants.xml为例,介绍如何自动生成各种语言的常量定义文件。同样,为了便于理解,在此我删掉了文件中的部分内容。与MapGuideApiGen.xml不同,Constants.xml包含一个新的元素Classes用来指出需要在目标语言中产生对应的常量类的C++类。
    <?xml version="1.0" encoding="UTF-8"?>

    <Parameters>

    <!-- 用于替换类型 -->

    <PHPTypeReplacements>
        <TypeReplacement oldtype="STRING" newtype="" />
        <TypeReplacement oldtype="INT16" newtype="" />
        ......
    </PHPTypeReplacements>
    <CSharpTypeReplacements>
        <TypeReplacement oldtype="STRING" newtype="string" />
        <TypeReplacement oldtype="INT16" newtype="short" />
        ......
    </CSharpTypeReplacements>
    <JavaTypeReplacements>
        <TypeReplacement oldtype="STRING" newtype="String" />
        <TypeReplacement oldtype="INT16" newtype="short" />
        ......
    </JavaTypeReplacements>

 

    <Namespace>OSGeo.MapGuide</Namespace>
    <Package>org.osgeo.mapguide</Package>

 

    <!-- 用于指出需要在目标语言中产生对应的常量类的C++类 -->

    <Classes>
        <Class name="MgMineType" />
        <Class name="MgPropertyType" />
        ......
    </Classes>

 

    <Headers>
        <Header path="../../../Common/Foundation/Data/MimeType.h" />
        <Header path="../../../Common/Foundation/Data/PropertyType.h" />
        ......
    </Headers>

 

    </Parameters>

 

    执行命令“IMake.exe Constants.xml C# Constants.cs”,IMake就帮我们自动生成了一个C#常量文件Constants.cs。对于文件/trunk/MgDev/Common/Foundation/Data/PropertyType.h中定义了如下常量,

    class MgPropertyType
    {
    PUBLISHED_API: 
       static const int Null     =  0;
       static const int Boolean  =  1;
       static const int Byte     =  2;
       static const int DateTime =  3;
       static const int Single   =  4;
       ......
    };

    在生成的Constants.cs文件中,有如下的类定义。
    class MgPropertyType
    { 
       static const int Null     =  0;
       static const int Boolean  =  1;
       static const int Byte     =  2;
       static const int DateTime =  3;
       static const int Single   =  4;
       ......
    };

    这个文件可以被C#的编译器直接编译,所以MapGuide没有使用SWIG生成常量的API,而是直接使用IMake。 如果想生成PHP或Java的常量定义文件,只需要将IMake命令的参数"C#"替换为"PHP"或"Jave"就可以了。

 

2.2 MapGuide对SWIG的修改
    在MapGuide开始使用SWIG的时候,可用的SWIG的最高版本是1.3.21,从那以后MapGuide在没有升级过SWIG。所以,到现在为止,MapGuide的SWIG版本仍然是1.3.21。这个版本的SWIG有不少限制和缺陷,

  • 无法创建基于自定义根异常类MgException的异常处理机制。
  • 无法创建属性(Property)。
  • 对某些方法无法产生正确的API。例如,如果方法GetA(...)返回的是类A的子类B的实例,SWIG创建的API返回的仍然是A类的实例。此时如果你把返回值转换为类B,那么转换会失败。
        A* GetA();
  • ......

    事实上最新的SWIG版本也没有全部解决这些问题,所以MapGuide对SWIG源代码进行了大量的修改,以满足自己的要求。看看MapGuide在使用SWIG命令是传入的参数,我们可以发现有许多参数不是SWIG标准的参数,例如proxydir、clsidcode、clsiddata、catchallcode等。


swig -c++ -csharp -dllname MapGuideUnmanagedApid -namespace OSGeo.MapGuide -proxydir ./custom -baseexception MgException -clsidcode getclassid.code -clsiddata m_cls_id -catchallcode catchall.code -dispose &quot;((MgDisposable*)arg1)-&gt;Release()&quot; -rethrow &quot;e-&gt;Raise();&quot; -nodefault -noconstants -module MapGuideApi -o MgApi_wrap.cpp -lib ../../../Oem/SWIGEx/Lib MapGuideApi.i


    在此,我们不打算一一介绍这些参数,因为在多数情况下你没有必要对了解参数的含义。我们只介绍MapGuide是如何来解决上述SWIG的第二和第三个问题的,因为在扩展MapGuide Web API的时候你可能会用得着。


2.2.1 创建属性
    如果你看过MapGuide源代码的话,你会发现有许多方法声明之后有“__get”、“__set”或“__get, __set”这样的注释,如类MgProperty中的方法。
    class MgProperty : public MgNamedSerializable
    {
    PUBLISHED_API:
        virtual INT16 GetPropertyType() = 0;  /// __get  
        STRING GetName();  /// __get, __set
        void SetName(CREFSTRING name);
        ......
};
    这些注释是有特殊含义的,它们就是用来解决上述SWIG的第二个问题的。当IMake工具扫描C++头文件时发现这注释后,会在目录“./custom”下为每个类产生一个帮助创建属性的代码文件。例如,如果要类MgProperty生成.NET API,IMake会在“./custom”生成一个文件名为MgProperty的C#代码文件,它的内容如下:
    public int PropertyType {
        get {return GetPropertyType(); }
    }
    public int Name {
        get { return GetPropertyType(); }
        set { setName(value);}
    }
    如果在SWIG的命令行中使用了参数proxydir,那么SWIG在为每个类生成代码的时候,会在proxydir所指定的目录下查找和类名相同的文件,并且将这个文件中的代码插入类的目标代码中。通过这种办法,就解决了上述SWIG的第二个问题。

 

2.2.2 ClassId
    MapGuide Web API中的所有类都是从MgObject继承而来的,在类MgObject中有一个方法GetClassId()用来返回每个类唯一的ID值。MapGuide就是用这个方法来解决上述SWIG的第三个问题的,所以如果要在MapGuide Web API中增加一个新类,一定要覆盖(override)这个方法,并且提供一个唯一的ID值。
    class MgObject
    {
    EXTERNAL_API:
        virtual INT32 GetClassId();
        virtual STRING GetClassName();
    INTERNAL_API:
        virtual ~MgObject();
        bool IsOfClass(INT32 classId);
    };

 

3. 扩展MapGudie Web API

    如果你发现现有的MapGuide Web API无法满足你的要求,没有关系,你可以去尝试扩展它,因为MapGuide是开源的。

    如果要新添类,基本步骤如下:
    (a) 修改C++代码,添加新的类。对于需要暴露于API的方法,使用宏PUBLISHED_API修饰。
    (b) 修改XML文件/trunk/MgDev/Web/src/MapGuideApi/MapGuideApiGen.xml的Headers部分,为每个新添加类所在的C++头文件增加一个Header元素。下面的示例中,"path"代表C++头文件的路径,"filename.h"代表文件的名称。
    <Headers>
        <Header path="path/filename.h" />
        ......
    </Headers>
    (c) 重新编译MapGuide的Web模块(/trunk/MgDev/Web/src/)。
 
    如果要增加一些新的方法到现有的类中,基本步骤如下:
    (a) 修改C++代码,添加新的方法,并且使用宏PUBLISHED_API修饰这些方法。
    (b) 重新编译MapGuide的Web模块(/trunk/MgDev/Web/src/)。

 

    如果要新增常量类,基本步骤如下:
    (a) 修改C++代码,添加新的常量类。
    (b) 修改XML文件/trunk/MgDev/Web/src/MapGuideApi/Constants.xml,在Classes部分为每个新添加常量类增加一个Class元素,在Headers部分为每个新添加常量类所在的C++头文件增加一个Header元素。下面的示例中,"ClassName"代表新添加的C++常量类的名称。

    <Classes>
        <Class name="ClassName" />
        ......
    </Classes>
    <Headers>
        <Header path="path/filename.h" />
        ......
    </Headers>   
    (c) 重新编译MapGuide的Web模块(/trunk/MgDev/Web/src/)。

C++中使用IXMLHTTPRequest对象调用Web API时,对URL中的特殊字符(或中文)编码 在调用Web API时,使用直接POST URL的方式实现。但是在拼接URL的时候很可能遇到特殊字符或者中文的情况。 本人对URL的研究很浅,想解决URL中特殊字符的情况,就看了下chrome地址栏中,如果输入有中文的话会自动编码为 %HH 格式(其实是UTF-8) const wchar_t * hexenc[] = { L"%00", L"%01", 阅读详情

相关推荐

从零开始构建C++ Web服务器

本文还有配套的精品资源,点击获取 简介:本文介绍了如何使用C++编程语言从头开始构建一个Web服务器,涵盖Web服务器的基本工作原理、HTTP协议、套接字编程、多线程处理、请求解析、文件系统交互、路由系统、错误处理和日志记录等关键概念。本项目有助于读者深入理解网络编程,并提高在计算机网络、操作系统和C++编程方面的技能。 1. HTTP协议基础与报文结构 H...

weixin_35903223的博客 2528

C++通信框架

有个C++的类库,解析三维模型文件的,放到Unity里面能够调用,但是有问题,基本的CreateFileA返回的结果是-1,错误代码是123,显示是路径错误,但是路径正气的,怀疑是不是从Unity里面运行不行。那考虑分开好了,通过通信的方式在Unity里面用c#调用c++,那就需要一个通信过程了,可以用最基本的tcp,但是我想找一个c++上的webapi服务端,就去找了。这个没问题,当前电脑网络有点奇怪,vpn开着可以下载,不开着这个下载不下来。第一次运行时不断下载相关的其他包,最后有个下载不了,卡住了。

llhswwha的专栏 2221

C++与Web通讯接口

windows平台C++与web平台通讯接口,可使用域名或ip+port的形式访问web端,通过参数决定使用POST还是GET方法

使用c++开发web后端接口

c++开发web后端接口,c++开发cgi程序

计算机辅助工程 3932

Web客户端:用CC ++编写的与REST API交互的Web客户端

Web客户端:用CC ++编写的与REST API交互的Web客户端

Unity透明视频播放全攻略:AVPro Video插件实战与避坑指南

在游戏开发与交互式内容创作中,视频播放是常见的多媒体需求。其核心原理在于通过解码器将压缩的视频数据流转换为连续的图像帧,再经由图形API渲染至屏幕。这项技术的价值在于能够高效地呈现动态视觉内容,广泛应用于游戏过场动画、UI特效、AR/VR虚拟展示等场景。当需求进阶到需要背景透明的视频时,技术实现复杂度显著增加,这涉及到对视频Alpha通道的编码、解码与渲染管线的特殊处理。本文聚焦于Unity引擎中实现高质量透明视频播放的工程实践,深入解析了AVPro Video这一专业插件如何解决原生VideoPlayer

weixin_30368981的博客 376

一. 安装工具 - Docker

学习用c++建服务器,第一步:下载所需工具docker+vscode,初步使用docker创建并运行Dockerfile。

weixin_43103339的博客 394

汇川EASY521 PLC实战指南:从硬件选型到程序架构与故障排查

可编程逻辑控制器(PLC)是工业自动化系统的核心大脑,其工作原理基于循环扫描机制,持续读取输入、执行用户程序并更新输出。这种确定性控制方式,使其在逻辑控制、顺序控制和运动控制中具有不可替代的技术价值,广泛应用于机械设备、生产线和过程控制等场景。对于汇川EASY521这类紧凑型高性能PLC,其核心优势在于集成了运动控制与丰富通讯接口,为中小型设备提供了高性价比的一站式解决方案。在实际应用中,工程师常需处理如“汇川sv660n”伺服驱动器的集成调试,或利用“hslcommunication”等开源库实现C#上位

weixin_42525264的博客 736

MapGuide HTTP API

本节将介绍什么是HTTP API,HTTP API与MapGuide Web API的关系,以及如何使用HTTP API。一般情况下,我们并不需要使用HTTP API,而且Viewer API已经包装了某些必需的HTTP API。如果不打算对Viewer API进行一些修改的话,可以忽略本节的内容。1.1.1        什么是HTTP API?如果查看客户端API的JavaScript

2459

全新RGB-D及平面法线数据集DIODE

丰田工业大学联合芝加哥大学和北航发布全新RGB-D及平面法线数据集 DIODE (Dense Indoor and Outdoor DEpth)。

qq_43477338的博客 1539

直击痛点:VS2015离线安装报错“安装包丢失或损坏”的根源分析与精准修复

本文深入剖析了Visual Studio 2015离线安装时出现“安装包丢失或损坏”报错的根本原因,指出问题核心在于安装程序固化的临时路径查找逻辑。文章提供了一步到位的精准修复方案,通过将ISO镜像中的完整packages文件夹复制到安装程序指定的临时路径,即可无需联网、无需操作证书直接解决问题,并对比分析了其他常见方法的局限性。

weixin_27734811的博客 357

【小沐学C++】C++实现Web服务器(libevent,libcurl,libuv,poco)

libevent - 一个事件通知库。目前,libevent支持 /dev/poll、 kqueue(2)、 event ports、 POSIX select(2)、 Windows select()、 poll(2)和epoll(4)。内部事件机制完全独立于暴露的事件 API,简单更新 libevent 即可提供新功能,而无需重新设计应用程序。结果,Libevent允许可移植的应用程序开发,并提供操作系统上可用的最具可扩展性的事件通知机制。...........................

爱看书的小沐 5048

用Arduino和RC522模块DIY一个NFC门禁卡复制器(附完整代码)

本文详细介绍了如何利用Arduino和RC522模块DIY一个NFC门禁卡复制器,包括硬件连接、软件配置、数据读写技术及完整代码实现。通过本教程,电子爱好者可以深入了解NFC技术,并构建自己的智能门禁系统,适用于家庭安全、办公场所等多种场景。

weixin_33704591的博客 500

c++高性能web框架drogon入门教程五:实例小项目,web和api实例代码

2020年11月30日15:30:09 c++高性能web框架drogon入门教程一 linux环境搭建和demo运行 c++高性能web框架drogon入门教程二 windows10下安装drogon,配合vscoede搭建开发环境 c++高性能web框架drogon入门教程三 控制器和数据库客户端使用 c++高性能web框架drogon入门教程四 orm使用,csp使用 c++高性能web框...

Z.X的博客 1122

基于Android平台下的健康管理APP/基于android的健康管理系统

随着网络科技的发展,移动智能终端逐渐走进人们的视线,相关应用越来越广泛,并在人们的日常生活中扮演着越来越重要的角色。因此,关键应用程序的开发成为影响移动智能终端普及的重要因素,设计并开发实用、方便的应用程序具有重要的意义和良好的市场前景。Android技术作为当前最流行的操作平台,自然也存在着大量的应用服务需求。 本课题研究的是基于Android技术平台的健康管理APP,开发这款健康管理APP主要是为了帮助用户可以不用约束时间与地点进行所需信息。本文详细讲述了健康管理APP的界面设计及使用,主要包括界面的

m0_73706453的博客 1437

TOPCon vs PERC:2024年光伏电站投资,哪种技术更划算?

本文深入分析了2024年光伏电站投资中TOPCon与PERC技术的财务表现。通过对比初始系统成本、全生命周期发电量及环境适应性,指出当前TOPCon组件与PERC价差已显著缩小,其更高的转换效率和更低的衰减率能有效降低度电成本并提升项目内部收益率,为投资者提供更具长期价值的方案。

p5l2m9n4o6q的博客 266

WebRTC的C/C++ API

WebRTC 的音频引擎封装了音频设备的统一接口, 使用者不用关心代码是 Windows, Mac OS X, Linux , iOS 或者 Android 等平台. 这也是一件非常棒的事情, 这个封装如果抽取出来, 就是一个优秀的跨平台音频接口(Audio API). 这里提供一个示例, 讲解如何使用 WebRTC 的 C/C++ API 进行录音和播放声音. 首先, 引入头文件:

woaitingting1985的博客 1万+

什么是plm系统?-数字化转型网

当今世界,产品研发能力是企业在激烈的市场竞争中保持战略优势的核心竞争力之一。如何有效地缩短产品研发周期、改善产品服务的设计迭代流程、有效降低产品的研发成本,也是企业面临的主要问题之一。PLM(Product Lifecycle Management,产品生命周期管理)在优化产品研发的全管理流程、增强企业产品的市场竞争力方面具有关键的作用。

cxo17757154043的博客 882

Web Servers and APIs using C++ 使用C ++的Web服务器和API Lynda课程中文字幕

Web Servers and APIs using C++ 中文字幕 使用C ++的Web服务器和API 中文字幕Web Servers and APIs using C++ C ++已经重新成为开发高性能网站和Web应用程序的首选语言 C ++编译为机器代码,使其更快启动和执行 对于用户来说,这意味着等待站点渲染的时间更少 本课程教授开发人员如何构建一个由MongoDB数据库驱动的网站,并使...

lyndacn的博客 421

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

基于c++的简易web服务器搭建(初尝socket编程)

实验的目的与要求: 用 Socket 编程实现一个 Web 服务器(端口号 8080) 实验要求: 该 Web 服务器在一台主机上运行,支持多台主机同时访问 有服务控制界面,开启和关闭按钮 能够指定主页(index.html) 测试方法: 在同组其他主机上,打开浏览器,输入 http://主机 IP 地址:8080,浏览器上显示主页 完成实验报告 系统设计原理 ocket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP

weixin_45816954的博客 6332

WebAPI学习(一)——创建Web API程序

在公司中用到的都是webAPI的应用程序,这个东西之前没有接触过。但是这个并不是什么新鲜的东西,因我们 之前有mvc的基础,所以说学习这个东西还是比较容易的,在开始的时候自己可能突然蒙圈了。因为在人家项目中用 到的东西自己之前都没有接触过,感觉非常的陌生甚至整个混乱了。但是当我们静下心来好好想想的话是非常容易 的,就是在某些写法上不太一样,其余的都差不多,下面就给大家创建第一个程序。

Jack 架构师之路 3万+

开源项目推荐:C++ Web/Http Server/Rest开发框架(请重点关注Oat++和搜狗workflow)

找了一些C++的Web开发框架,看样子不少,有许多是基于Qt的,似乎第一个CppCMS这个名字比较大些。 1. CppCMShttp://cppcms.com/wikipp/en/page/main 以高性能著称,MVC,内容较全,包括数据库、会话等管理,内置http server 2. TreeFroghttp://www.treefrogframework.org/ 以Qt为基础开发的,MVC......

$firecat利白的代码足迹$ 2万+

C++语言的Web开发

随着互联网技术的飞速发展,Web开发逐渐成为软件开发领域的重要组成部分。在众多的编程语言中,C++因其强大的性能和灵活性,虽然并不是最广泛使用的Web开发语言,但在特定场合下仍然有其不可替代的优势。本文将深入探讨C++在Web开发中的应用及其优势、劣势,并结合实际案例来分析其在当今Web开发中的地位。

2501_90407350的博客 542

告别Python Flask?用C++的Crow框架5分钟搭建你的第一个Web API

本文介绍了如何利用C++的Crow框架快速搭建Web API,特别适合Python Flask开发者迁移到高性能C++开发。Crow框架以其极简API设计、现代C++17支持和无依赖部署等优势,显著提升性能表现,QPS可达Flask的5-8倍。文章详细展示了从环境配置到构建完整RESTful API的全过程,并提供了中间件、性能优化等高级技巧。

weixin_26854555的博客 401

【C++】libwebsockets库的简易教程(附源码)

【C++】libwebsockets库的简易教程

bigger_belief的博客 1万+
上一篇: MapGuide的历史
下一篇: MapGuide的系统架构
MapGuide_Inside
博客等级 码龄17年 340粉丝 71原创
评论 4
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值