JNI is wanky. Finally about to return an object from C++ to Java/Kotlin

This commit is contained in:
kdeng00
2019-10-05 17:30:37 -04:00
parent d3bcbd28ef
commit 33ac4c6fcf
86 changed files with 761 additions and 226 deletions
+2
View File
@@ -13,6 +13,8 @@ cmake_minimum_required(VERSION 3.4.1)
# set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY BOTH)
set(CMAKE_CXX11_EXTENSION_COMPILE_OPTION "-std=c++17")
set (SOURCES
Demo.cpp
SongRepository.cpp
+67
View File
@@ -20,12 +20,33 @@
#include "model/Song.h"
#include "model/User.h"
#include "SongRepository.h"
#include "Tok.h"
model::Song retrieveSong(const std::string&);
std::string fetchToken(const std::string&, const std::string&, const std::string&);
model::Song retrieveSong(const std::string& token)
{
repository::SongRepository songRepo;
model::Song song;
song.id = 2;
song.title = "Smooth";
song.album = "Amaze";
song.artist = "The Herb";
song.genre = "Blazing";
song.duration = 420;
song.year = 420;
song = songRepo.retrieveSong(token, song.id);
return song;
}
std::string fetchToken(const std::string& username, const std::string& password,
const std::string& apiUri)
{
@@ -57,3 +78,49 @@ Java_com_example_mear_activities_DemoStreamActivity_logUser(
return env->NewStringUTF(token.c_str());
}
extern "C"
JNIEXPORT jobject
JNICALL
Java_com_example_mear_activities_DemoStreamActivity_retrieveSong(
JNIEnv *env,
jobject thisObj,
jstring token
)
{
const std::string tok = env->GetStringUTFChars(token, NULL);
auto song = retrieveSong(tok);
std::string bank = "SBI Bank";
jclass songClass = env->FindClass( "com/example/mear/models/Song");
jmethodID jconstructor = env->GetMethodID( songClass, "<init>", "()V" );
jobject songObj = env->NewObject( songClass, jconstructor );
jmethodID songId = env->GetMethodID( songClass, "setId", "(I)V" );
jmethodID songTitle = env->GetMethodID( songClass, "setTitle", "(Ljava/lang/String;)V" );
jmethodID songAlbum = env->GetMethodID( songClass, "setAlbum", "(Ljava/lang/String;)V" );
jmethodID songArtist = env->GetMethodID( songClass, "setArtist", "(Ljava/lang/String;)V" );
jmethodID songGenre = env->GetMethodID( songClass, "setGenre", "(Ljava/lang/String;)V" );
jmethodID songDuration = env->GetMethodID( songClass, "setDuration", "(I)V" );
jmethodID songYear = env->GetMethodID( songClass, "setYear", "(I)V" );
jint id = song.id;
jstring title = env->NewStringUTF(song.title.c_str());
jstring album = env->NewStringUTF(song.album.c_str());
jstring artist = env->NewStringUTF(song.artist.c_str());
jstring genre = env->NewStringUTF(song.genre.c_str());
jint duration = song.duration;
jint year = song.year;
env->CallVoidMethod( songObj, songId, id );
env->CallVoidMethod(songObj, songTitle, title);
env->CallVoidMethod(songObj, songAlbum, album);
env->CallVoidMethod(songObj, songArtist, artist);
env->CallVoidMethod(songObj, songGenre, genre);
env->CallVoidMethod(songObj, songDuration, duration);
env->CallVoidMethod(songObj, songYear, year);
return songObj;
}
+58
View File
@@ -4,6 +4,9 @@
#include "SongRepository.h"
#include <curl/curl.h>
#include <nlohmann/json.hpp>
namespace repository {
// TODO: implement this
std::vector<model::Song> SongRepository::fetchSongs(const std::string& token,
@@ -13,4 +16,59 @@ namespace repository {
return songs;
}
model::Song SongRepository::retrieveSong(const std::string& token, const int id) {
std::string uri;
uri.append(std::to_string(id));
model::Song song;
CURL *curl;
CURLcode res;
struct curl_slist *chunk = NULL;
curl = curl_easy_init();
if (!curl) {
return song;
}
auto resp = std::make_unique<char[]>(10000);
std::string authInfo("Authorization: Bearer ");
authInfo.append(token);
chunk = curl_slist_append(chunk, authInfo.c_str());
curl_easy_setopt(curl, CURLOPT_URL, uri.c_str());
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, respBodyRetriever);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, resp.get());
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
if (res == CURLE_OK) {
auto s = nlohmann::json::parse(resp.get());
song.id = s["id"].get<int>();
song.title = s["title"].get<std::string>();
song.album = s["album"].get<std::string>();
song.artist = s["artist"].get<std::string>();
song.genre = s["genre"].get<std::string>();
song.duration = s["duration"].get<int>();
song.year = s["year"].get<int>();
return song;
}
return song;
}
size_t SongRepository::respBodyRetriever(void* ptr, size_t size, size_t nmemb, char *e)
{
std::memcpy(e, ptr, nmemb);
e[nmemb] = '\0';
return nmemb;
}
}
+3
View File
@@ -15,7 +15,10 @@ namespace repository {
class SongRepository {
public:
std::vector<model::Song> fetchSongs(const std::string&, const std::string&);
model::Song retrieveSong(const std::string&, const int);
private:
static size_t respBodyRetriever(void*, size_t, size_t, char*);
};
}
+4 -3
View File
@@ -4,6 +4,7 @@
#include "Tok.h"
#include <memory>
#include <cstring>
#include <curl/curl.h>
@@ -20,7 +21,7 @@ namespace manager {
return "none";
}
char resp[2048];
auto resp = std::make_unique<char[]>(10000);
const auto loginUri = fetchLoginUri(uri);
const auto obj = userJsonString(user);
@@ -28,14 +29,14 @@ namespace manager {
curl_easy_setopt(curl, CURLOPT_URL, loginUri.c_str());
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, obj.c_str());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, respBodyRetriever);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, resp);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, resp.get());
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
if (res == CURLE_OK) {
auto s = nlohmann::json::parse(resp);
auto s = nlohmann::json::parse(resp.get());
return s["token"].get<std::string>();
}
+1
View File
@@ -5,6 +5,7 @@
#ifndef MEAR_TOK_H
#define MEAR_TOK_H
#include <memory>
#include <string>
#include "model/User.h"
@@ -9,6 +9,8 @@ import kotlinx.android.synthetic.main.activity_demo_stream.*
import kotlinx.android.synthetic.main.content_demo_stream.*
import org.jetbrains.anko.toast
import com.example.mear.models.Song
class DemoStreamActivity : AppCompatActivity() {
companion object {
@@ -18,7 +20,11 @@ class DemoStreamActivity : AppCompatActivity() {
}
private var token: String? = null
private external fun logUser(usr: String, pass: String, api: String): String
private external fun retrieveSong(tok: String): Song
override fun onCreate(savedInstanceState: Bundle?) {
@@ -50,8 +56,9 @@ class DemoStreamActivity : AppCompatActivity() {
var passwordStr = password.text.toString()
var apiUriStr = apiUri.text.toString()
var token = logUser(usernameStr, passwordStr, apiUriStr)
toast(token).show()
token = logUser(usernameStr, passwordStr, apiUriStr)
toast(token!!).show()
var s = retrieveSong(token!!);
}
private fun validFields(): Boolean {
@@ -0,0 +1,4 @@
package com.example.mear.models
class Song (var id: Int = 3, var title: String = "", var album: String = "", var artist: String = "",
var genre: String = "", var year: Int = 0, var duration: Int = 0)