澳门新浦京娱乐场网站-www.146.net-新浦京娱乐场官网
做最好的网站

C语言不定参数,Service服务端和客商端程序

前边多个高品质总括之二:asm.js & webassembly

2017/10/21 · HTML5 · webassembly

原稿出处: magicly   

前一篇咱俩说了要缓和高品质总括的几个措施,贰个是并发用WebWorkers,另四个便是用更底层的静态语言。

2011年,Mozilla的程序员Alon Zakai在研究LLVM编写翻译器时突发奇想:能或不能够把C/C 编写翻译成Javascript,并且尽量到达Native代码的进程吗?于是她开垦了Emscripten编写翻译器,用于将C/C 代码编写翻译成Javascript的叁个子集asm.js,质量差不离是原生代码的八分之四。大家能够看看这个PPT。

之后Google开发了C语言不定参数,Service服务端和客商端程序。Portable Native Client,也是一种能让浏览器运营C/C 代码的本领。 后来推测大家都是为各搞各的要命啊,居然谷歌(Google), Microsoft, Mozilla, Apple等几家大商号联合进行同盟开拓了叁个面向Web的通用二进制和文本格式的类型,那正是WebAssembly,官互连网的介绍是:

WebAssembly or wasm is a new portable, size- and load-time-efficient format suitable for compilation to the web.

WebAssembly is currently being designed as an open standard by a W3C Community Group that includes representatives from all major browsers.

所以,WebAssembly相应是一个前景很好的种类。大家得以看一下当下浏览器的扶植情形: 澳门新浦京娱乐场网站 1

安装信赖

   数组一旦被定义了,它的维数和维界就不会变。因而,除了结构的初步化和销毁之外,数组唯有存取元素和改动成分。数组日常分为行序和列许。平日系统都是用的行许。
以2维数组a[m][n]为例
列序:
a[0][0]  a[1][0] ...... a[m-1][0]
.............
a[m-1][0] a[m-1][1] ...... a[m-1][n-1]

1、作用表达:

近日,际遇多少个c语言的波动参数难点。其实,对于c语言的不安参数难题,只须求多个函数就足以化解了。那三个函数的头文件是<stdarg.h>,其实下边包车型地铁多个函数都以二个宏定义(macro)。
    那三个函数是:
    void va_start(va_list ap, last);
    type va_arg(va_list ap, type);
    void va_end(va_list ap);
    假使急需开展别的的片段操作,能够查阅一下man手册进行询问。
    在此多个函数解释在此以前,先看二个变量va_list,这些变量的品种是如何吗?通过查阅内核源代码,平昔追踪下去,才发觉它的等级次序是void *类型的。
    对于va_start(va_list ap, last)函数,那个函数是用来开首化指针变量ap(va_list类型)的,今后管理参数就是私下认可从ap处开始拍卖。last平时为char *传过来参数列表的首先个参数。
    对于va_arg(va_list ap, type)函数来讲,便是将ap指针根据type类型向后运动,然后抽取ap指针所指的百般参数。
    对于va_end(va_list ap)一般和va_start(va_list ap, last)配套使用,做一些善后管理的事务。
    这里有一个难题,当我们取参数的时候,如何判别大家要取的参数已经取完了?开头动和自动小编是如此想的,通过va_arg的再次来到值进行剖断,通过查阅资料,都是那般说的,看来小编的估算是对的。当自身把程序写出来举行测验的时候,开采不是如此的:
#include <stdio.h>
#include <stdarg.h>
int sum(const int , ...);
int main(void)
{
    printf("The result is:%d/n", sum(10, 9, 8));
    return 0;
}
int sum(const int first, ...)
{
    va_list argp;
    int sum = 0;
    int tmp;
    va_start(argp, first);
    sum = first;
    printf("%d/n", first);
    while((tmp = va_arg(argp, int)) != 0) {
        printf("%d/n", tmp);
        sum = tmp;
    }
    va_end(argp);
    return sum;
}
那个程序的运行结果是:
10
9
8
6676468
134513824
The result is:141190319
    那些结果表达,通过va_arg的再次回到值举行参数是不是取完来判断是有有失常态态的。
    会不会是透过argp的值来判别的啊?让我们来做个测量试验:
#include <stdio.h>
#include <stdarg.h>
int sum(const int , ...);
int main(void)
{
    printf("The result is:%d/n", sum(10, 9, 8));
    return 0;
}
int sum(const int first, ...)
{
    va_list argp;
    int sum = 0;
    int tmp;
    va_start(argp, first);
    sum = first;
    printf("%d/n", first);
    while(argp) {
        tmp = va_arg(argp, int);
        printf("%d/n", tmp);
        sum = tmp;
    }
    va_end(argp);
    return sum;
}
    这一个顺序的施行结果抢先作者的料想,现身了段错误。
    至于怎么着修改那一个程序把不定参数抽出来,我要么尚未找到消除方法。后来,笔者想开了printf()函数,小编翻看了它的源代码,个中第一是调用了vsprintf()函数,至于何以调用vsprintf()函数,作者想恐怕是为着落到实处类似于fprintf()之类的函数调用的方便人民群众,那样也抓牢了函数的利用率。printf()函数的要紧代码:
328 va_start(args, fmt);
329 n = vsprintf(sprint_buf, fmt, args);
330 va_end(args);
    小编延续查看了vsprintf()函数,结果开掘,在这里个函数当中,它如同是由此判别字符串当中“%”号的略微来决定背后参数的个数的。想到这里,小编决断,在想调用不定参数那样的函数的时候,其实是急需提出参数的个数的,只是是通过直接的点子。比如大家最纯熟的printf()函数,其实大家在率先个参数此中,通过%号已经建议了参数的个数,不是吗?
    想到这里,作者想开了事先看见man手册中付出的例证为何是这么的:
#include <stdio.h>
       #include <stdarg.h>
       void
       foo(char *fmt, ...)
       {
           va_list ap;
           int d;
           char c, *s;
           va_start(ap, fmt);
           while (*fmt)
               switch (*fmt ) {
               case 's': /* string */
                   s = va_arg(ap, char *);
                   printf("string %s/n", s);
                   break;
               case 'd': /* int */
                   d = va_arg(ap, int);
                   printf("int %d/n", d);
                   break;
               case 'c': /* char */
                   /* need a cast here since va_arg only
                      takes fully promoted types */
                   c = (char) va_arg(ap, int);
                   printf("char %c/n", c);
                   break;
               }
           va_end(ap);
       }
    这里的话,不是就经过第三个参数内定之后才读取的吧?其实本人觉着是直接的报告了参数的个数。
    通过上边的分析,上边做了多个简易的兵连祸结参数的使用。
    难题陈诉:给定一些字符串,求出它们的最长起来字串。
    实验代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
void fun(char *fmt, ...);
int main()
{
    fun("sss", "fanabcd", "fanfanfanfan", "fanyyyyyyyyyyyy");//sss 表示了天崩地裂参数的个数
    return 0;    
}
void fun(char *fmt, ...)
{
    va_list argp;
    char * str, res[C语言不定参数,Service服务端和客商端程序。20] = {0};
    int i;
    va_start(argp, fmt);
    if(*fmt == 's') {
        str = va_arg(argp, char *);
        strcpy(res, str);
    }
    fmt ;
    while(*fmt) {
        if(*fmt == 's') {
            str = va_arg(argp, char *);
            i = 0;
            while(res[i] != '/0') {
                if(res[i] != str[i]) {
                    res[i] = 0;
                    break;
                }
                i ;
            }
        }
    }
    va_end(argp);
    printf("The result is:%s/n", res);
}
    程序的实行结果是:
The result is:fan
    通过如此的折腾,就把c语言的不安参数轻巧地采纳起来了

安装Emscripten

访问

  1. 下载对应平台版本的SDK

  2. 通过emsdk获取最新版工具

JavaScript

# Fetch the latest registry of available tools. ./emsdk update # Download and install the latest SDK tools. ./emsdk install latest # Make the "latest" SDK "active" for the current user. (writes ~/.emscripten file) ./emsdk activate latest # Activate PATH and other environment variables in the current terminal source ./emsdk_env.sh

1
2
3
4
5
6
7
8
9
10
11
# Fetch the latest registry of available tools.
./emsdk update
 
# Download and install the latest SDK tools.
./emsdk install latest
 
# Make the "latest" SDK "active" for the current user. (writes ~/.emscripten file)
./emsdk activate latest
 
# Activate PATH and other environment variables in the current terminal
source ./emsdk_env.sh
  1. 将下列加多随地境变量PATH中

JavaScript

~/emsdk-portable ~/emsdk-portable/clang/fastcomp/build_incoming_64/bin ~/emsdk-portable/emscripten/incoming

1
2
3
~/emsdk-portable
~/emsdk-portable/clang/fastcomp/build_incoming_64/bin
~/emsdk-portable/emscripten/incoming
  1. 其他

笔者在执行的时候蒙受报错说LLVM本子不对,后来参谋文档配置了LLVM_ROOT变量就好了,假设你未有赶过难题,能够忽视。

JavaScript

LLVM_ROOT = os.path.expanduser(os.getenv('LLVM', '/home/ubuntu/a-path/emscripten-fastcomp/build/bin'))

1
LLVM_ROOT = os.path.expanduser(os.getenv('LLVM', '/home/ubuntu/a-path/emscripten-fastcomp/build/bin'))
  1. 申明是不是安装好

执行emcc -v,若是设置好会产出如下音讯:

JavaScript

emcc (Emscripten gcc/clang-like replacement linker emulating GNU ld) 1.37.21 clang version 4.0.0 ( 974b55fd84ca447c4297fc3b00cefb6394571d18) ( 9e4ee9a67c3b67239bd1438e31263e2e86653db5) (emscripten 1.37.21 : 1.37.21) Target: x86_64-apple-darwin15.5.0 Thread model: posix InstalledDir: /Users/magicly/emsdk-portable/clang/fastcomp/build_incoming_64/bin INFO:root:(Emscripten: Running sanity checks)

1
2
3
4
5
6
emcc (Emscripten gcc/clang-like replacement linker emulating GNU ld) 1.37.21
clang version 4.0.0 (https://github.com/kripken/emscripten-fastcomp-clang.git 974b55fd84ca447c4297fc3b00cefb6394571d18) (https://github.com/kripken/emscripten-fastcomp.git 9e4ee9a67c3b67239bd1438e31263e2e86653db5) (emscripten 1.37.21 : 1.37.21)
Target: x86_64-apple-darwin15.5.0
Thread model: posix
InstalledDir: /Users/magicly/emsdk-portable/clang/fastcomp/build_incoming_64/bin
INFO:root:(Emscripten: Running sanity checks)

Node.js(0.8 or above; 0.10.17 or above to run websocket-using servers in node):

行序列:
a[0][0]  a[1][0] ...... a[m-1][0]
.............
a[0][n-1] a[1][ [n-1 ] ...... a[m-1][n-1]
数量貌似选拔一而再的地点存款和储蓄。总计的法子为 (i, j) = &a (b) j;//b 一维成分的个数
加大到多维数组中(j1, j2, j3,.....,jn) = (b2*b3*...*bn * j1 b3*b4*...*bn*j2 ..... bn *jn-1 jn)
诸如:已知数组a[5][4][10]。求a[2][3][4] 的地址;
j1=2、j2 = 3、j3 = 4;b1=5、b2=4、b3=10;
a[2][3][4]=b2*b3*j1 b3*j2 j3=4*10*2 10*3 4;

       要费用的Web Service功效特别轻巧,正是多少个add函数,将五个参数相加,重返其和。

Hello, WebAssembly!

创制二个文书hello.c

JavaScript

#include <stdio.h> int main() { printf("Hello, WebAssembly!n"); return 0; }

1
2
3
4
5
#include <stdio.h>
int main() {
  printf("Hello, WebAssembly!n");
  return 0;
}

编译C/C 代码:

JavaScript

emcc hello.c

1
emcc hello.c

上述命令会转换叁个a.out.js文件,大家能够直接用Node.js执行:

JavaScript

node a.out.js

1
node a.out.js

输出

JavaScript

Hello, WebAssembly!

1
Hello, WebAssembly!

为了让代码运转在网页里面,实施上边发号施令会转换hello.htmlhello.js五个公文,在那之中hello.jsa.out.js内容是全然同样的。

emcc hello.c -o hello.html<code>

1
2
emcc hello.c -o hello.html<code>
 

JavaScript

➜ webasm-study md5 a.out.js MD5 (a.out.js) = d7397f44f817526a4d0f94bc85e46429 ➜ webasm-study md5 hello.js MD5 (hello.js) = d7397f44f817526a4d0f94bc85e46429

1
2
3
4
➜  webasm-study md5 a.out.js
MD5 (a.out.js) = d7397f44f817526a4d0f94bc85e46429
➜  webasm-study md5 hello.js
MD5 (hello.js) = d7397f44f817526a4d0f94bc85e46429

下一场在浏览器展开hello.html,能够看来页面 澳门新浦京娱乐场网站 2

前方生成的代码都以asm.js,毕竟Emscripten是住家小编Alon Zakai最初用来扭转asm.js的,私下认可输出asm.js也就相差为奇了。当然,能够透过option生成wasm,会变卦多个公文:hello-wasm.html, hello-wasm.js, hello-wasm.wasm

JavaScript

emcc hello.c -s WASM=1 -o hello-wasm.html

1
emcc hello.c -s WASM=1 -o hello-wasm.html

接下来浏览器展开hello-wasm.html,开掘报错TypeError: Failed to fetch。原因是wasm文本是经过XHR异步加载的,用file:////做客会报错,所以大家须求启四个服务器。

JavaScript

npm install -g serve serve

1
2
npm install -g serve
serve

然后访问http://localhost:5000/hello-wasm.html,就能够看见寻常结果了。

Python2.x (2.7.3 or above preferred)

上面为代码完毕。(以下代码是本人在ubuntu中轻易测量检验通过。如在别的系统中不或许运营,请见谅。本代码只透过简短的测验,假诺出现难点,请见谅。)
[plain]
/* 
*created by Reage at 2013 March 28 
*description: 数组的贯彻,包涵创建、赋值、访谈、打字与印刷 

*blog: 
*/ 
#include <stdio.h> 
#include <stdlib.h> 
#include <stdarg.h> 
 
 
#define MAXDIM 4 
 
typedef struct Array 

    int dim; 
    int *ptr; 
    int *bounds; 
    int *base_add; 
}Array; 
 
int array_init(Array *a, int dim, ...); 
int array_set_value(Array *a, int value, ...); 
int array_print_line(Array *a); 
int array_get_value(Array *a, ...); 
void array_destory(Array *a); 
 
int main(int argc, char *argv[]) 

    Array a; 
    int i = 0; 
    int j; 
    int total = 1; 
    array_init(&a, 2, 4, 6); 
     
    for(; i < 4; i ) 
    { 
        for(j = 0; j < 6; j ) 
        { 
            array_set_value(&a, total , i, j); 
        } 
    } 
 
    array_print_line(&a); 
    for(i = 0; i < 4; i ) 
    { 
        for(j = 0; j < 6; j ) 
        { 
            printf("%-7d",array_get_value(&a,  i, j)); 
        } 
        printf("n"); 
    } 
    array_destory(&a); 

 
int array_init(Array * a, int dim, ...) 

    if(1 > dim || 8 < dim) 
        return -1; 
    a->dim = dim; 
 
    va_list ap; 
    int i; 
    long total = 1; 
 
    a->bounds = (int *)malloc(dim * sizeof(int)); 
     
    va_start(ap, dim); 
    for(i = 0; i < dim; i ) 
    { 
        a->bounds[i] = va_arg(ap, int); 
        total *= a->bounds[i]; 
    } 
    va_end(ap); 
 
    a->ptr = (int *) malloc(total * sizeof(int)); 
 
    a->base_add = (int *) malloc(dim * sizeof(int)); 
    a->base_add[dim -1] = 1; 
    i = dim -2; 
    for(; i >= 0; i--) 
    { 
        a->base_add[i] = a->base_add[i 1] * a->bounds[i 1]; 
    } 
 
    return 0; 

 
#define FREE(x) if(NULL != (x)) free(x) 
 
void array_destory(Array *a) 

    FREE(a->ptr); 
    FREE(a->bounds); 
    FREE(a->base_add); 

 
int array_get_value(Array *a, ...) 

    va_list va; 
    va_start(va, a); 
     
    int result = array_get_locate(a, va); 
    if(-1 == result) return -1; 
    return a->ptr[result]; 

 
 
int array_print_line(Array *a) 

    int total = 1; 
    int i = 0; 
    int line ; 
    for(; i < a->dim; i ) 
    { 
        total *= a->bounds[i]; 
    } 
     
    line = total/a->bounds[0]; 
    for(i = 0; i < total; i ) 
    { 
        if(0 == i % line && 0 != i) printf("n"); 
        printf("%-7d", a->ptr[i]); 
    } 
    printf("n"); 
    return 0; 

 
 
int array_get_locate(Array *a, va_list va) 

    int result = 0; 
    int bound; 
    int i; 
    for(i = 0; i < a->dim; i ) 
    { 
        bound = va_arg(va, int); 
        if(0 > bound || bound > a->bounds[i]) 
        { 
            return -1; 
        } 
        result = bound * a->base_add[i]; 
    } 
    return result; 

 
int array_set_value(Array *a, int value, ...) 

    if(NULL == a) return -1; 
    va_list va; 
    va_start(va, value); 
 
    int result = array_get_locate(a, va); 
    if( -1 == result) return -1; 
 
    a->ptr[result]澳门新浦京娱乐场网站, = value; 
    return 0; 

 

调用C/C 函数

前面的Hello, WebAssembly!都是main函数直接打出去的,而小编辈利用WebAssembly的目的是为着高质量计算,做法多半是用C/C 实现有些函数实行耗费时间的揣摸,然后编译成wasm,暴露给js去调用。

在文件add.c中写如下代码:

JavaScript

#include <stdio.h> int add(int a, int b) { return a b; } int main() { printf("a b: %d", add(1, 2)); return 0; }

1
2
3
4
5
6
7
8
9
#include <stdio.h>
int add(int a, int b) {
  return a b;
}
 
int main() {
  printf("a b: %d", add(1, 2));
  return 0;
}

有两种艺术能够把add办法暴表露来给js调用。

Java(1.6.0_31 or later). Java is optional. It is required to use theClosure Compiler(in order to minify your code).

/*
*created by Reage at 2013 March 28
*description: 数组的达成,包涵创造、赋值、访谈、打字与印刷
*
*blog:
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>

2、C版本的次第:

通过命令行参数揭穿API

JavaScript

emcc -s EXPORTED_FUNCTIONS="['_add']" add.c -o add.js

1
emcc -s EXPORTED_FUNCTIONS="['_add']" add.c -o add.js

在意方法名add前必须加_。 然后我们能够在Node.js里头这么使用:

JavaScript

// file node-add.js const add_module = require('./add.js'); console.log(add_module.ccall('add', 'number', ['number', 'number'], [2, 3]));

1
2
3
// file node-add.js
const add_module = require('./add.js');
console.log(add_module.ccall('add', 'number', ['number', 'number'], [2, 3]));

执行node node-add.js会输出5。 借使急需在web页面使用以来,推行:

JavaScript

emcc -s EXPORTED_FUNCTIONS="['_add']" add.c -o add.html

1
emcc -s EXPORTED_FUNCTIONS="['_add']" add.c -o add.html

下一场在扭转的add.html中投入如下代码:

JavaScript

<button onclick="nativeAdd()">click</button> <script type='text/javascript'> function nativeAdd() { const result = Module.ccall('add', 'number', ['number', 'number'], [2, 3]); alert(result); } </script>

1
2
3
4
5
6
7
  <button onclick="nativeAdd()">click</button>
  <script type='text/javascript'>
    function nativeAdd() {
      const result = Module.ccall('add', 'number', ['number', 'number'], [2, 3]);
      alert(result);
    }
  </script>

接下来点击button,就足以看看进行结果了。

Module.ccall会直接调用C/C 代码的法门,更通用的情景是大家得到到三个封装过的函数,能够在js里面一再调用,那亟需用Module.cwrap,具体细节能够参见文档。

JavaScript

const cAdd = add_module.cwrap('add', 'number', ['number', 'number']); console.log(cAdd(2, 3)); console.log(cAdd(2, 4));

1
2
3
const cAdd = add_module.cwrap('add', 'number', ['number', 'number']);
console.log(cAdd(2, 3));
console.log(cAdd(2, 4));

Gitclient. Git is required if building tools from source.

#define MAXDIM 4

(1)头文件:SmsWBS.h,注释部分不可少,url部分的IP必得填写当前Linux计算机的IP

概念函数的时候增进EMSCRIPTEN_KEEPALIVE

丰硕文件add2.c

JavaScript

#include <stdio.h> #include <emscripten.h> int EMSCRIPTEN_KEEPALIVE add(int a, int b) { return a b; } int main() { printf("a b: %d", add(1, 2)); return 0; }

1
2
3
4
5
6
7
8
9
10
11
#include <stdio.h>
#include <emscripten.h>
 
int EMSCRIPTEN_KEEPALIVE add(int a, int b) {
  return a b;
}
 
int main() {
  printf("a b: %d", add(1, 2));
  return 0;
}

执行命令:

JavaScript

emcc add2.c -o add2.html

1
emcc add2.c -o add2.html

同样在add2.html中增加代码:

JavaScript

<button onclick="nativeAdd()">click</button> <script type='text/javascript'> function nativeAdd() { const result = Module.ccall('add', 'number', ['number', 'number'], [2, 3]); alert(result); } </script>

1
2
3
4
5
6
7
  <button onclick="nativeAdd()">click</button>
  <script type='text/javascript'>
    function nativeAdd() {
      const result = Module.ccall('add', 'number', ['number', 'number'], [2, 3]);
      alert(result);
    }
  </script>

只是,当您点击button的时候,报错:

JavaScript

Assertion failed: the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)

1
Assertion failed: the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)

能够通过在main()中添加emscripten_exit_with_live_runtime()解决:

JavaScript

#include <stdio.h> #include <emscripten.h> int EMSCRIPTEN_KEEPALIVE add(int a, int b) { return a b; } int main() { printf("a b: %d", add(1, 2)); emscripten_exit_with_live_runtime(); return 0; }

1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>
#include <emscripten.h>
 
int EMSCRIPTEN_KEEPALIVE add(int a, int b) {
  return a b;
}
 
int main() {
  printf("a b: %d", add(1, 2));
  emscripten_exit_with_live_runtime();
  return 0;
}

抑或也能够直接在命令行中增多-s NO_EXIT_RUNTIME=1来解决,

JavaScript

emcc add2.c -o add2.js -s NO_EXIT_RUNTIME=1

1
emcc add2.c -o add2.js -s NO_EXIT_RUNTIME=1

只是会报三个警戒:

JavaScript

exit(0) implicitly called by end of main(), but noExitRuntime, so not exiting the runtime (you can use emscripten_force_exit, if you want to force a true shutdown)exit(0) implicitly called by end of main(), but noExitRuntime, so not exiting the runtime (you can use emscripten_force_exit, if you want to force a true shutdown)

1
exit(0) implicitly called by end of main(), but noExitRuntime, so not exiting the runtime (you can use emscripten_force_exit, if you want to force a true shutdown)exit(0) implicitly called by end of main(), but noExitRuntime, so not exiting the runtime (you can use emscripten_force_exit, if you want to force a true shutdown)

就此提出选取第一种格局。

上述变动的代码都是asm.js,只供给在编译参数中增添-s WASM=1中就可以转换wasm,然后选拔格局都一样。

Fastcomp(Emscripten’s fork of LLVM and Clang)

参照链接地址:Manually Building Emscripten on Mac OS X

To build the Fastcomp code from source:

Create a directory to store the build. It doesn’t matter where, because Emscripten gets the information from thecompiler configuration file (~/.emscripten). We show how to update this file later in these instructions:

mkdirmyfastcompcdmyfastcomp

Clone the fastcomp LLVM repository (https://github.com/kripken/emscripten-fastcomp):

gitclone

Clone thekripken/emscripten-fastcomp-clangrepository intoemscripten-fastcomp/tools/clang:

cdemscripten-fastcompgitclone tools/clang

Warning

Youmustclone it into a directory namedclangas shown, so thatClangis present intools/clang!

Create abuilddirectory (inside theemscripten-fastcompdirectory) and then navigate into it:

mkdirbuildcdbuild

Configure the build usingeithercmakeor theconfigurescript:

Usingcmake:

cmake..-DCMAKE_BUILD_TYPE=Release-DLLVM_TARGETS_TO_BUILD="X86;JSBackend"-DLLVM_INCLUDE_EXAMPLES=OFF-DLLVM_INCLUDE_TESTS=OFF-DCLANG_INCLUDE_EXAMPLES=OFF-DCLANG_INCLUDE_TESTS=OFF

Note

On Windows add the-G"VisualStudio10Win64"directive to build using Visual Studio (Visual Studio 2011 and 2012 do NOT work).

Usingconfigure(Linux/Mac only):

../configure--enable-optimized--disable-assertions--enable-targets=host,js

Determine the number of available cores on your system (Emscripten can run many operations in parallel, so using more cores may have a significant impact on compilation time):

On Mac OS X you can get the number of cores using:Apple menu | About this mac | More info | System report. TheHardware overviewon the resulting dialog includes aTotal number of coresentry.

On Linux you can find the number of cores by entering the following command on the terminal:cat/proc/cpuinfo|grep"^cpucores"|uniq.

On Windows the number of cores is listed on theTask Manager | Performance Tab. You can open theTask Managerby enteringCtrl Shift Escfrom the Desktop.

Callmaketo build the sources, specifying the number of available cores:

make-j4

Note

If the build completes successfully,clang,clang , and a number of other files will be created in the release directory (/build/Release/bin).

The final step is to update the~/.emscriptenfile, specifying the location offastcompin theLLVM_ROOTvariable.

Note

If you’re building thewholeof Emscripten from source, following the platform-specific instructions inBuilding Emscripten from Source, you won’t yet have Emscripten installed. In this case, skip this step and return to those instructions.

If you already have an Emscripten environment (for example if you’re building Fastcomp using the SDK), then setLLVM_ROOTto the location of theclangbinary under thebuilddirectory. This will be something like/build/Release/binor/build/bin:

```

vim ~/.emscripten

```

修改 LLVM_ROOT到钦命的文件目录

LLVM_ROOT = '/usr/local/myfastcomp/emscripten-fastcomp/build/bin' # directory

typedef struct Array
{
    int dim;
    int *ptr;
    int *bounds;
    int *base_add;
}Array;

//gsoap ns service name: SmsWBS
//gsoap ns service style: rpc
//gsoap ns service namespace: http://192.168.2.161:8000/SmsWBS.wsdl
//gsoap ns service location: http://192.168.2.161:8000
//gsoap ns service encoding: encoded
//gsoap ns schema namespace: urn:SmsWBS

用asm.js和WebAssembly试行耗费时间测算

前方企图干活都做完了, 现在我们来试一下用C代码来优化前一篇中提过的题目。代码很简短:

JavaScript

// file sum.c #include <stdio.h> // #include <emscripten.h> long sum(long start, long end) { long total = 0; for (long i = start; i <= end; i = 3) { total = i; } for (long i = start; i <= end; i = 3) { total -= i; } return total; } int main() { printf("sum(0, 1000000000): %ld", sum(0, 1000000000)); // emscripten_exit_with_live_runtime(); return 0; }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// file sum.c
#include <stdio.h>
// #include <emscripten.h>
 
long sum(long start, long end) {
  long total = 0;
  for (long i = start; i <= end; i = 3) {
    total = i;
  }
  for (long i = start; i <= end; i = 3) {
    total -= i;
  }
  return total;
}
 
int main() {
  printf("sum(0, 1000000000): %ld", sum(0, 1000000000));
  // emscripten_exit_with_live_runtime();
  return 0;
}

注意用gcc编写翻译的时候须求把跟emscriten连锁的两行代码注释掉,不然编写翻译可是。 大家先直接用gcc编译成native code拜候代码运维多块呢?

JavaScript

➜ webasm-study gcc sum.c ➜ webasm-study time ./a.out sum(0, 1000000000): 0./a.out 5.70s user 0.02s system 99% cpu 5.746 total ➜ webasm-study gcc -O1 sum.c ➜ webasm-study time ./a.out sum(0, 1000000000): 0./a.out 0.00s user 0.00s system 64% cpu 0.003 total ➜ webasm-study gcc -O2 sum.c ➜ webasm-study time ./a.out sum(0, 1000000000): 0./a.out 0.00s user 0.00s system 64% cpu 0.003 total

1
2
3
4
5
6
7
8
9
➜  webasm-study gcc sum.c
➜  webasm-study time ./a.out
sum(0, 1000000000): 0./a.out  5.70s user 0.02s system 99% cpu 5.746 total
➜  webasm-study gcc -O1 sum.c
➜  webasm-study time ./a.out
sum(0, 1000000000): 0./a.out  0.00s user 0.00s system 64% cpu 0.003 total
➜  webasm-study gcc -O2 sum.c
➜  webasm-study time ./a.out
sum(0, 1000000000): 0./a.out  0.00s user 0.00s system 64% cpu 0.003 total

能够看见有未有优化差异照旧异常的大的,优化过的代码实施时间是3ms!。really?留心思忖,小编for循环了10亿次哟,每便for施行大约是三回加法,一回赋值,一次比较,而作者一共做了两遍for循环,也正是说最少是100亿次操作,而自己的mac pro是2.5 GHz Intel Core i7,所以1s应有也就实施25亿次CPU指令操作吧,怎么大概逆天到这种程度,肯定是何地错了。想起在此以前看来的一篇rust测验品质的篇章,说rust直接在编译的时候算出了答案, 然后把结果直接写到了编写翻译出来的代码里, 不知道gcc是或不是也做了看似的作业。在果壳网上GCC中-O1 -O2 -O3 优化的原理是怎么着?那篇小说里, 还真有loop-invariant code motion(LICM)针对for的优化,所以笔者把代码扩大了部分if决断,希望能“糊弄”得了gcc的优化。

JavaScript

#include <stdio.h> // #include <emscripten.h> // long EMSCRIPTEN_KEEPALIVE sum(long start, long end) { long sum(long start, long end) { long total = 0; for (long i = start; i <= end; i = 1) { if (i % 2 == 0 || i % 3 == 1) { total = i; } else if (i % 5 == 0 || i % 7 == 1) { total = i / 2; } } for (long i = start; i <= end; i = 1) { if (i % 2 == 0 || i % 3 == 1) { total -= i; } else if (i % 5 == 0 || i % 7 == 1) { total -= i / 2; } } return total; } int main() { printf("sum(0, 1000000000): %ld", sum(0, 100000000)); // emscripten_exit_with_live_runtime(); return 0; }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <stdio.h>
// #include <emscripten.h>
 
// long EMSCRIPTEN_KEEPALIVE sum(long start, long end) {
long sum(long start, long end) {
  long total = 0;
  for (long i = start; i <= end; i = 1) {
    if (i % 2 == 0 || i % 3 == 1) {
      total = i;
    } else if (i % 5 == 0 || i % 7 == 1) {
      total = i / 2;
    }
  }
  for (long i = start; i <= end; i = 1) {
    if (i % 2 == 0 || i % 3 == 1) {
      total -= i;
    } else if (i % 5 == 0 || i % 7 == 1) {
      total -= i / 2;
    }
  }
  return total;
}
 
int main() {
  printf("sum(0, 1000000000): %ld", sum(0, 100000000));
  // emscripten_exit_with_live_runtime();
  return 0;
}

施行结果大致要符合规律一些了。

JavaScript

➜ webasm-study gcc -O2 sum.c ➜ webasm-study time ./a.out sum(0, 1000000000): 0./a.out 0.32s user 0.00s system 99% cpu 0.324 total

1
2
3
➜  webasm-study gcc -O2 sum.c
➜  webasm-study time ./a.out
sum(0, 1000000000): 0./a.out  0.32s user 0.00s system 99% cpu 0.324 total

ok,大家来编写翻译成asm.js了。

JavaScript

#include <stdio.h> #include <emscripten.h> long EMSCRIPTEN_KEEPALIVE sum(long start, long end) { // long sum(long start, long end) { long total = 0; for (long i = start; i <= end; i = 1) { if (i % 2 == 0 || i % 3 == 1) { total = i; } else if (i % 5 == 0 || i % 7 == 1) { total = i / 2; } } for (long i = start; i <= end; i = 1) { if (i % 2 == 0 || i % 3 == 1) { total -= i; } else if (i % 5 == 0 || i % 7 == 1) { total -= i / 2; } } return total; } int main() { printf("sum(0, 1000000000): %ld", sum(0, 100000000)); emscripten_exit_with_live_runtime(); return 0; }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <stdio.h>
#include <emscripten.h>
 
long EMSCRIPTEN_KEEPALIVE sum(long start, long end) {
// long sum(long start, long end) {
  long total = 0;
  for (long i = start; i <= end; i = 1) {
    if (i % 2 == 0 || i % 3 == 1) {
      total = i;
    } else if (i % 5 == 0 || i % 7 == 1) {
      total = i / 2;
    }
  }
  for (long i = start; i <= end; i = 1) {
    if (i % 2 == 0 || i % 3 == 1) {
      total -= i;
    } else if (i % 5 == 0 || i % 7 == 1) {
      total -= i / 2;
    }
  }
  return total;
}
 
int main() {
  printf("sum(0, 1000000000): %ld", sum(0, 100000000));
  emscripten_exit_with_live_runtime();
  return 0;
}

执行

JavaScript

emcc sum.c -o sum.html

1
emcc sum.c -o sum.html

然后在sum.html中增多代码``

JavaScript

<button onclick="nativeSum()">NativeSum</button> <button onclick="jsSumCalc()">JSSum</button> <script type='text/javascript'> function nativeSum() { t1 = Date.now(); const result = Module.ccall('sum', 'number', ['number', 'number'], [0, 100000000]); t2 = Date.now(); console.log(`result: ${result}, cost time: ${t2 - t1}`); } </script> <script type='text/javascript'> function jsSum(start, end) { let total = 0; for (let i = start; i <= end; i = 1) { if (i % 2 == 0 || i % 3 == 1) { total = i; } else if (i % 5 == 0 || i % 7 == 1) { total = i / 2; } } for (let i = start; i <= end; i = 1) { if (i % 2 == 0 || i % 3 == 1) { total -= i; } else if (i % 5 == 0 || i % 7 == 1) { total -= i / 2; } } return total; } function jsSumCalc() { const N = 100000000;// 总次数1亿 t1 = Date.now(); result = jsSum(0, N); t2 = Date.now(); console.log(`result: ${result}, cost time: ${t2 - t1}`); } </script>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<button onclick="nativeSum()">NativeSum</button>
  <button onclick="jsSumCalc()">JSSum</button>
  <script type='text/javascript'>
    function nativeSum() {
      t1 = Date.now();
      const result = Module.ccall('sum', 'number', ['number', 'number'], [0, 100000000]);
      t2 = Date.now();
      console.log(`result: ${result}, cost time: ${t2 - t1}`);
    }
  </script>
  <script type='text/javascript'>
    function jsSum(start, end) {
      let total = 0;
      for (let i = start; i <= end; i = 1) {
        if (i % 2 == 0 || i % 3 == 1) {
          total = i;
        } else if (i % 5 == 0 || i % 7 == 1) {
          total = i / 2;
        }
      }
      for (let i = start; i <= end; i = 1) {
        if (i % 2 == 0 || i % 3 == 1) {
          total -= i;
        } else if (i % 5 == 0 || i % 7 == 1) {
          total -= i / 2;
        }
      }
 
      return total;
    }
    function jsSumCalc() {
      const N = 100000000;// 总次数1亿
      t1 = Date.now();
      result = jsSum(0, N);
      t2 = Date.now();
      console.log(`result: ${result}, cost time: ${t2 - t1}`);
    }
  </script>

别的,大家修改成编写翻译成WebAssembly看看效果啊?

JavaScript

emcc sum.c -o sum.js -s WASM=1

1
emcc sum.c -o sum.js -s WASM=1
Browser webassembly asm.js js
Chrome61 1300ms 600ms 3300ms
Firefox55 600ms 800ms 700ms
Safari9.1 不支持 2800ms 因不支持ES6我懒得改写没测试

深感Firefox有一点不客观啊, 默认的JS太强了啊。然后以为webassembly也不曾特意强啊,忽地开采emcc编译的时候从不点名牌产品优质产品化增选-O2。再来二次:``

JavaScript

emcc -O2 sum.c -o sum.js # for asm.js emcc -O2 sum.c -o sum.js -s WASM=1 # for webassembly

1
2
emcc -O2 sum.c -o sum.js # for asm.js
emcc -O2 sum.c -o sum.js -s WASM=1 # for webassembly
Browser webassembly -O2 asm.js -O2 js
Chrome61 1300ms 600ms 3300ms
Firefox55 650ms 630ms 700ms

依旧没什么变化, 适得其反。堪称asm.js能够完成native的二分一进程么,那一个倒是好像到达了。然而今年Compiling for the Web with WebAssembly (Google I/O ‘17)里说WebAssembly是1.2x slower than native code,以为窘迫呢。asm.js再有一个平价是,它正是js,所以就算浏览器不协助,也能当成不一样的js施行,只是未有加速效果。当然WebAssembly遭到各大商家一致重申,作为四个新的行业内部,确定前景会越来越好,期望会有更加好的显现。

TheEmscripten code, from GitHub

clone emscripten项目到地头

```

git clone

cd emscripten

npm install

```

测验是还是不是各依赖景况已经正确安装成功

在emscripten目录下运作

```

./emcc tests/hello_world.cpp

```

设若未有报错则会在同目录下找到二个新文件a.out.js

后日能够透过nodejs来运营a.out.js这些文件了

```

node a.out.js

```

会在调控台打字与印刷出

```

hello, world!

```

通过browserify编译使之能在浏览器运行

安装browserify

```

sudo npm install browserify -g

```

编译a.out.js文件

```

browserify a.out.js > test.js

```

现在可以在网页中引入test.js文件

```

<script src='test.js'></script>

```

打开控制台可以看到

```

hello world

```

能够在输出的时候一直钦点声称为浏览器端运维的代码,

./emcc tests/hello_world.cpp -o test.html

在js中调用c /c写的函数

Module.ccap("function_name", return_type, arg_type, arg)

int array_init(Array *a, int dim, ...);
int array_set_value(Array *a, int value, ...);
int array_print_line(Array *a);
int array_get_value(Array *a, ...);
void array_destory(Array *a);

int ns__add(int num1, int num2, int *sum);
其一头文件须要当心的是,后面包车型大巴 // 部分是有含义的,能够在地点修改,假诺完全去掉,将会促成变化的中间文件区别,由此会挑起要修改Makefile文件                                           

Rust

自然还想写Rust编写翻译成WebAssembly的,可是以为本文已经太长了, 中期再写就算结合Rust做WebAssembly吧。

焦急的能够先看看这两篇

  • Compiling to the web with Rust and emscripten
  • Rust ⇋ JavaScript

行使emscritpen输入代码优化

./emcc tests/hello-test.cpp -o function.js

代码是透过点名牌产品优品化的优化参数运转时,EMCC。等第包蕴:-O0(不优化),-O1,-O2,-Os,-OZ和-O3

添加setting

-s EXPORTED_FUNCTIONS="['_uncompress']"  //各处函数

-s  NO_FILESYSTEM=1      //0 在代码中包含文件系统代码, 1在代码中不带有文件系统代码

-s EXPORTED_RUNTIME_METHODS    //随处能够在模块中动用的函数

[

'FS_createFolder',

'FS_createPath',

'FS_createDataFile',

'FS_createPreloadedFile',

'FS_createLazyFile',

'FS_createLink',

'FS_createDevice',

'FS_unlink',

'Runtime',

'ccall',

'cwrap',

'setValue',

'getValue',

'ALLOC_NORMAL',

'ALLOC_STACK',

'ALLOC_STATIC',

'ALLOC_DYNAMIC',

'ALLOC_NONE',

'allocate',

'getMemory',

'Pointer_stringify',

'AsciiToString',

'stringToAscii',

'UTF8ArrayToString',

'UTF8ToString',

'stringToUTF8Array',

'stringToUTF8',

'lengthBytesUTF8',

'stackTrace',

'addOnPreRun',

'addOnInit',

'addOnPreMain',

'addOnExit',

'addOnPostRun',

'intArrayFromString',

'intArrayToString',

'writeStringToMemory',

'writeArrayToMemory',

'writeAsciiToMemory',

'addRunDependency',

'removeRunDependency',

];

Building Projects

编译多个c /c文件到二个js中

# Sub-optimal - JavaScript optimizations are omitted

./emcc -O2 a.cpp -o a.bc

./emcc -O2 b.cpp -o b.bc

./emcc a.bc b.bc -o project.js

# Sub-optimal - LLVM optimizations omitted

./emcc a.cpp -o a.bc

./emcc b.cpp -o b.bc

./emcc -O2 a.bc b.bc -o project.js

# Broken! Different JavaScript and LLVM optimisations used.

./emcc -O1 a.cpp -o a.bc

./emcc -O2 b.cpp -o b.bc

./emcc -O3 a.bc b.bc -o project.js

# Correct. The SAME LLVM and JavaScript options are provided at both levels.

./emcc -O2 a.cpp -o a.bc

./emcc -O2 b.cpp -o b.bc

./emcc -O2 a.bc b.bc -o project.js

int main(int argc, char *argv[])
{
    Array a;
    int i = 0;
    int j;
    int total = 1;
    array_init(&a, 2, 4, 6);
   
    for(; i < 4; i )
    {
        for(j = 0; j < 6; j )
        {
            array_set_value(&a, total , i, j);
        }
    }

(2)Makefile文件:

Refers

  • 1 赞 收藏 评论

澳门新浦京娱乐场网站 3

    array_print_line(&a);
    for(i = 0; i < 4; i )
    {
        for(j = 0; j < 6; j )
        {
            printf("%-7d",array_get_value(&a,  i, j));
        }
        printf("n");
    }
    array_destory(&a);
}

正如根本,倘诺头文件中的 // 部分有修改,要反省是否要修改Makefile文件

int array_init(Array * a, int dim, ...)
{
    if(1 > dim || 8 < dim)
        return -1;
    a->dim = dim;

GSOAP_ROOT=/usr/local/gSOAP
WSNAME0=soap
WSNAME=SmsWBS
CC=g -g -DWITH_NONAMESPACES
INCLUDE=-I $(GSOAP_ROOT)/include
SERVER_OBJS=$(WSNAME0)C.o $(WSNAME0)Server.o stdsoap2.o
CLIENT_OBJS=$(GSOAP_ROOT)/env/envC.o $(WSNAME0)ClientLib.o stdsoap2.o
ALL_OBJS=${WSNAME}server.o $(WSNAME0)C.o $(WSNAME0)Server.o ${WSNAME}test.o $(WSNAME0)ClientLib.o
#GSOAP_SRC=/usr/local/gsoap-2.7/gsoap

    va_list ap;
    int i;
    long total = 1;

all:server

    a->bounds = (int *)malloc(dim * sizeof(int));
   
    va_start(ap, dim);
    for(i = 0; i < dim; i )
    {
        a->bounds[i] = va_arg(ap, int);
        total *= a->bounds[i];
    }
    va_end(ap);

${WSNAME}.wsdl:${WSNAME}.h
        $(GSOAP_ROOT)/bin/soapcpp2 -c $(GSOAP_ROOT)/import ${WSNAME}.h

    a->ptr = (int *) malloc(total * sizeof(int));

stdsoap2.o:$(GSOAP_ROOT)/src/stdsoap2.c
        $(CC) -c $? $(INCLUDE)

    a->base_add = (int *) malloc(dim * sizeof(int));
    a->base_add[dim -1] = 1;
    i = dim -2;
    for(; i >= 0; i--)
    {
        a->base_add[i] = a->base_add[i 1] * a->bounds[i 1];
    }

$(ALL_OBJS):%.o:%.c
        $(CC) -c $? $(INCLUDE)

    return 0;
}

server:Makefile ${WSNAME}.wsdl ${WSNAME}server.o $(SERVER_OBJS)
        $(CC) ${WSNAME}server.o $(SERVER_OBJS) -o ${WSNAME}server

#define FREE(x) if(NULL != (x)) free(x)

client:Makefile ${WSNAME}.wsdl ${WSNAME}test.c $(ALL_OBJS) stdsoap2.o
        $(CC) ${WSNAME}test.o $(CLIENT_OBJS) -o ${WSNAME}test

void array_destory(Array *a)
{
    FREE(a->ptr);
    FREE(a->bounds);
    FREE(a->base_add);
}

clean:
        rm -f *.o *.xml *.a *.wsdl *.nsmap $(WSNAME0)H.h $(WSNAME0)C.c $(WSNAME0)Server.c $(WSNAME0)Client.c $(WSNAME0)Stub.* $(WSNAME)$(WSNAME)Proxy.* $(WSNAME)$(WSNAME)Object.* $(WSNAME0)ServerLib.c $(WSNAME0)ClientLib.c $(WSNAME)server ns.xsd $(WSNAME)test

int array_get_value(Array *a, ...)
{
    va_list va;
    va_start(va, a);
   
    int result = array_get_locate(a, va);
    if(-1 == result) return -1;
    return a->ptr[result];
}

 

int array_print_line(Array *a)
{
    int total = 1;
    int i = 0;
    int line ;
    for(; i < a->dim; i )
    {
        total *= a->bounds[i];
    }
   
    line = total/a->bounds[0];
    for(i = 0; i < total; i )
    {
        if(0 == i % line && 0 != i) printf("n");
        printf("%-7d", a->ptr[i]);
    }
    printf("n");
    return 0;
}

(3)服务端程序SmsWBSserver.c:

int array_get_locate(Array *a, va_list va)
{
    int result = 0;
    int bound;
    int i;
    for(i = 0; i < a->dim; i )
    {
        bound = va_arg(va, int);
        if(0 > bound || bound > a->bounds[i])
        {
            return -1;
        }
        result = bound * a->base_add[i];
    }
    return result;
}

#include "soapH.h"
#include "SmsWBS.nsmap"

int array_set_value(Array *a, int value, ...)
{
    if(NULL == a) return -1;
    va_list va;
    va_start(va, value);

int main(int argc, char **argv)
{
        int m, s;               /* master and slave sockets */
        struct soap SmsWBS_soap;

    int result = array_get_locate(a, va);
    if( -1 == result) return -1;

        soap_init(&SmsWBS_soap);

    a->ptr[result] = value;
    return 0;
}

        soap_set_namespaces(&SmsWBS_soap, namespaces);

 

        if (argc < 2)
        {
                printf("usage: %s <server_port> n", argv[0]);
                exit(1);
        }
        else
        {
                m = soap_bind(&SmsWBS_soap, NULL, atoi(argv[1]), 100);
                if (m < 0)
                {
                        soap_print_fault(&SmsWBS_soap, stderr);
                        exit(-1);
                }

...

                fprintf(stderr, "Socket connection successful: master socket = %dn", m);

                for (;;)
                {
                        s = soap_accept(&SmsWBS_soap);

                        if (s < 0)
                        {
                                soap_print_fault(&SmsWBS_soap, stderr);
                                exit(-1);
                        }

                        fprintf(stderr, "Socket connection successful: slave socket = %dn", s);
                        soap_serve(&SmsWBS_soap);
                        soap_end(&SmsWBS_soap);
                }

       }

        return 0;
}

int ns__add(struct soap *add_soap, int num1, int num2, int *sum)
{
        *sum = num1 num2;
        return 0;
}

 

(4)顾客端程序SmsWBStest.c:

#include <stdio.h>
#include <stdlib.h>
#include "soapStub.h"
#include "SmsWBS.nsmap"

int add(const char *server, int num1, int num2, int *sum);

int add(const char *server, int num1, int num2, int *sum)
{
        struct soap SmsWBS_soap;
        int result = 0;

        soap_init(&SmsWBS_soap);
        soap_set_namespaces(&SmsWBS_soap, namespaces);

        soap_call_ns__add(&SmsWBS_soap, server, "", num1, num2, sum);

        if(SmsWBS_soap.error)
        {
                printf("soap error:%d, %s, %s ", SmsWBS_soap.error, *soap_faultcode(&SmsWBS_soap), *soap_faultstring(&SmsWBS_soap));
                result = SmsWBS_soap.error;
         }

        soap_end(&SmsWBS_soap);
        soap_done(&SmsWBS_soap);

        return result;
}

int main(int argc, char **argv)
{
        int result = -1;
        char* server="http://localhost:8000";

        int num1 = 0;
        int num2 = 0;
        int sum = 0;

        if( argc < 3 )
        {
                printf("usage: %s num1 num2 n", argv[0]);
                exit(0);

        }

        num1 = atoi(argv[1]);
        num2 = atoi(argv[2]);

        result = add(server, num1, num2, &sum);
        if (result != 0)
        {
                printf("soap err, errcode = %d n", result);
        }
        else
        {
                printf("%d %d = %d n", num1, num2, sum);
        }

        return 0;
}

(5)编写翻译和周转:

日前都早已希图好了,以往只需求:

make                                     ---获得服务端程序SmsWBSserver

make client                            ---得到客户端程序SmsWBStest

SmsWBSserver 八千             ----运营服务端程序

出来类似上边包车型客车体现就意味着运转如常

Socket connection successful: master socket = 3

再运转客商端程序:

SmsWBStest 67 78

显示:

67 78 = 145

调用Web Service成功

本文由澳门新浦京娱乐场网站发布于新浦京娱乐场官网,转载请注明出处:C语言不定参数,Service服务端和客商端程序