在网上找了一圈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 allCXX = g++
CXXFLAGS = -std=c++11 -g
LDFLAGS = -lcurlone_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 程序执行结果: