AWS 基于Lambda + Layer实现 调用C++动态包

燕烨
2023-12-01

Lambda搭建在linux平台上,基于windows的.dll文件无法调用,需要准备.so文件

lib.cpp

#include<iostream>
#include<string>

using namespace std;

extern "C"{
    int sum(int x,int y){
        return x + y;
    }

    int times(int x,int y){
        return x * y;
    }
}

使用g++编译

g++ lib.cpp -shared -fPIC -o lib.so

1.使用python 实现

把lib.so放在python/路径下打包上传,或者直接用S3上传layers,这样在执行lambda时会在opt文件夹下找到上传的文件,这种方式更多用于加载依赖包。要注意文件的大小,超过10M的话只能使用S3。

Lambda代码

import json, os
from ctypes import *

def lambda_handler(event, context):
    
    # pDLL = WinDLL("./lib.so")
    # pDll = windll.LoadLibrary("./lib.so")
    # pDll = cdll.LoadLibrary("./lib.so")
    #在opt下找到上传的so库
    pDll = CDLL("/opt/python/lib.so")
    
    #从event获取参数
    num1 = event.get("num1")
    num2 = event.get("num2")
    #调用C++函数
    res1 = pDll.sum(num1,num2)
    print(res1)
    res2 = pDll.times(num1,num1)
    print(res2)
   
    return {
        'statusCode': 200,
        'body': json.dumps({
            'result1' : res1,
            'result1' : res2
        })
    }

2.使用java实现

把lib.so放在java/路径下打包上传,或者直接用S3上传layers,同样在执行lambda时会在opt文件夹下找到上传的文件。同时需要准备跨平台使用C++的jar包jna。

java代码

在使用lambda之前,首先在本地的linux上测试

package com.test

import com.sun.jna.Native

public class Call{
    
    static{
        // 注册动态库
        Native.register("libName");
    }

    // 声明动态库的方法
    public static native int sum(int x,int y);

    public static native int times(int x,int y);

    public static void main(String[] args){

        System.out.printin(Call.sum(22,33));
        System.out.printin(Call.times(22,33));
    }

}
#编译 -应用jar包时,需要用-cp指令,在linux环境,多个jar包需要用:连接
javac -cp /home/user/jna-4.0.0.jar /home/user/com/test/Call.java

#执行
java -cp ".:/home/user/jna-4.0.0.jar"  /home/user/com/test/Call

实现aws提供的hander

package com.amazonaws.lambda.demo;

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;

public class test implements RequestHandler<Map<String,String>, String> {

    @Override
    public String handleRequest(Map<String,String>input, Context context) {
        context.getLogger().log("Input: " + input);
        // 从input获取参数传入C++方法
        Intager res =  Call.sum(Integer.valueOf(input.get("num1")),Integer.valueOf(input.get("num2")));
        return new String(res);
    }

}

导出jar包,上传到lambda,和把jna的jar包单独上传到layers同时也导入lambda

更改Runtime settings指定Handler为实际的包名.类名::hander名

com.amazonaws.lambda.demo.test::handleRequest即可

 类似资料: