C++代码实现调用OpenAi接口Api

在网上找了一圈C++如何调用OpenAi的接口,找到的例子比较简单,完全照搬下来修改一下也能用,不过i整合在自己的类里面就莫名奇妙的问题:

1. 比如 coredump

     url_easy_perform的执行和curl_easy_setopt放在了两个函数中就出问题了,很奇怪。。。至今不知道原因,有知道的小伙伴可以评论告诉我。O(∩_∩)O

    暖心提示:

    curl_easy_setopt和url_easy_perform 别分开写。

2. 发送api key,放入head中时,

     curl_slist_append的返回值必须用同一个head指针来接收才行,例如:

     struct curl_slist* headers

      curl_slist_append(this->headers, contentType_header.c_str());

       curl_slist_append(this->headers, contentType_header.c_str());

       就会导致认证失败,因为必须:

       headers = curl_slist_append(this->headers, contentType_header.c_str());

       headers = curl_slist_append(this->headers, contentType_header.c_str());

       你以为就这?还有:

       你下一次使用前要把 headers = NULL才行(贴个没问题的代码截图如下):

       

    ======================================================================

上示例代码:

sudo apt install nlohmann-json3-dev

Ubuntu 22.04上面安装下上面的json库

1. openai.h

#pragma once

#include <nlohmann/json_fwd.hpp>
#include <nlohmann/json.hpp>
#include <curl/curl.h>
#include <string>
using namespace std;
using namespace nlohmann;

class OpenAi {
    public:
        static OpenAi* GetInstance();
        ~OpenAi();
        const std::string& GetClassName();
        void Initialize();
        void Finalitialize();
        void SetModel(const std::string& model = "gpt-3.5-turbo");
        void SetUri(const std::string& uri = "https://api.openai.com/v1/chat/completions");
        void SetApiKey(const std::string& apiKey);
        void SetRole(const std::string& role = "user");
        void SetContent(const std::string& content);
        void SetContentType(const std::string& contentType = "application/json");
        void PostMessage();
        std::string GetResponse();
        void Reset();
        void Test();
    private:
        OpenAi();
        std::string _className;
        std::string _model;
        std::string _uri;
        std::string _apiKey;
        std::string _role;
        std::string _content;
        std::string _contentType;
        nlohmann::json request;
    private:
        struct curl_slist* headers;
        CURL* curl;
        std::string response;
        CURLcode res;
        void set_curl_headers();
        void set_curl_request();
        static size_t WriteCallback(void* contents, size_t size, size_t nmemb, string* response);
};

2. openai.cpp

#include <exception>
#include <iostream>
#include <ostream>
#include <string>
#include "openai.h"
static OpenAi* openai_instance = nullptr;

OpenAi::OpenAi():_className("OpenAi"),
                 headers(nullptr),
                 curl(nullptr) {
    curl_global_init(CURL_GLOBAL_DEFAULT);
}
OpenAi::~OpenAi() {
    curl_global_cleanup();
}
const std::string& OpenAi::GetClassName() {
    return _className;
}

void OpenAi::Initialize() {
    this->curl = curl_easy_init();
    this->SetModel();
    this->SetUri();
    this->SetRole();
    this->SetContentType();
}

void OpenAi::Finalitialize() {
    if(this->curl) {
        curl_easy_cleanup(this->curl);
        this->curl = nullptr;
    }
    if(this->headers) {
        curl_slist_free_all(headers);
        this->headers = nullptr;
    }
    if(openai_instance) {
        delete openai_instance;
        openai_instance = nullptr;
    }
}

OpenAi* OpenAi::GetInstance() {
    if(openai_instance == nullptr) {
        openai_instance = new OpenAi();
    }

    return openai_instance;
}

void OpenAi::SetModel(const std::string& model) {
    this->_model.assign(model);
}

void OpenAi::SetUri(const std::string& uri) {
    this->_uri.assign(uri);
}

void OpenAi::SetApiKey(const std::string& apiKey) {
    this->_apiKey.assign(apiKey);
}

void OpenAi::SetRole(const std::string& role) {
    this->_role.assign(role);
}

void OpenAi::SetContent(const std::string& content) {
    this->_content.assign(content);
}

void OpenAi::SetContentType(const std::string& contentType) {
    this->_contentType.assign(contentType);
}

void OpenAi::PostMessage() {
    this->set_curl_headers();
    this->set_curl_request();
}

void OpenAi::set_curl_headers() {
    std::string contentType_header = "Content-Type: " + this->_contentType;
    std::string auth_header = "Authorization: Bearer " + this->_apiKey;
    std::cout<<contentType_header<<std::endl;
    std::cout<<auth_header<<std::endl;
    if(this->headers) {
        curl_slist_free_all(headers);
        this->headers = nullptr;
    }
    this->headers = curl_slist_append(this->headers, contentType_header.c_str());
    this->headers = curl_slist_append(this->headers, auth_header.c_str());
    curl_easy_setopt(this->curl, CURLOPT_HTTPHEADER, this->headers);
}
void OpenAi::set_curl_request() {
    //std::cout<<__func__<<":"<<__LINE__<<std::endl;
    std::string prompt = this->_content;
    json requestData;
    if(!this->response.empty()) {
        this->response.clear();
    }
    this->request["model"] = this->_model;
    this->request["messages"][0]["role"] = this->_role;
    this->request["messages"][0]["content"] = this->_content;
    this->request["temperature"] = 0;
    string requestDataStr = this->request.dump().c_str();
    std::cout<<requestDataStr<<std::endl;
    curl_easy_setopt(this->curl, CURLOPT_URL, this->_uri.c_str());
    curl_easy_setopt(this->curl, CURLOPT_POSTFIELDS, requestDataStr.c_str());
    curl_easy_setopt(this->curl, CURLOPT_POSTFIELDSIZE, requestDataStr.length());
    curl_easy_setopt(this->curl, CURLOPT_WRITEFUNCTION, OpenAi::WriteCallback);
    curl_easy_setopt(this->curl, CURLOPT_WRITEDATA, &this->response);
    //std::cout<<__func__<<":"<<__LINE__<<std::endl;
    this->res = curl_easy_perform(this->curl);
}

std::string OpenAi::GetResponse() {
    if (this->res != CURLE_OK) {
        std::cerr << "Failed to make request: " << curl_easy_strerror(res) << std::endl;
    } else {
        // Process the API response here
        //std::cout<<__func__<<":"<<__LINE__<<std::endl;
        if(!this->response.empty()) {
            //std::cout<<__func__<<":"<<__LINE__<<"->Response:"<<std::endl;
            //std::cout<<this->response<<std::endl;
            try {
                json jresponse = json::parse(this->response);
                std::cout<<jresponse.dump()<<std::endl;
            } catch(std::exception& e) {
                std::cout<<e.what()<<std::endl;
            }
        }
    }

    return this->response;
}

size_t OpenAi::WriteCallback(void* contents, size_t size, size_t nmemb, string* response) {
    size_t totalSize = size * nmemb;
    response->append((char*)contents, totalSize);
    return totalSize;
}

void OpenAi::Reset() {
    this->SetModel();
    this->SetUri();
    this->SetRole();
    this->SetContentType();
}
void OpenAi::Test() {
    if (this->curl) {
        this->set_curl_headers();
        this->set_curl_request();
    }
}
 

 3. 测试程序文件 openai_self.cpp

#include <iostream>
#include <string>
#include "openai.h"

using namespace std;
using namespace nlohmann;

int main(int argc, char** argv) {
    int ret = 0;
    OpenAi* openai = OpenAi::GetInstance();
    openai->Initialize();
    openai->SetApiKey("");  // 设置你自己的API Key
    openai->SetModel();
    openai->SetContent("Who are you?");
    openai->PostMessage();
    std::string res = openai->GetResponse();
    if(!res.empty()) {
        std::cout<<"Response ->:"<<std::endl;
        std::cout<<res<<std::endl;
    } else {
        std::cout<<"No response!"<<std::endl;
    }

    return ret;
}
 

 4. makefile

.DEFAULT_GOAL := openai
.PHONY: openai all

CXX = g++
CXXFLAGS = -std=c++11 -g
LDFLAGS = -lcurl

one_sources = openai_self.cpp openai.cpp

all: openai
    @echo "===== $@ start ====="
    @echo "===== $@ end ====="

openai:
    @echo "===== $@ start ====="
    $(CXX) $(CXXFLAGS) $(one_sources) -o $@ $(LDFLAGS)
    @echo "===== $@ end ====="
clean_openai:
    @echo "===== $@ start ====="
    @rm -rf openai
    @echo "===== $@ end ====="

clean: clean_openai
    @echo "===== $@ start ====="
    @echo "===== $@ end ====="
 

 5. 直接执行 make命令编译出openai程序

6. ./openai 程序执行结果:

   

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值