I have a header file with definition:
typedef enum acamera_metadata_enum_android_lens_facing {
// enumeration
} acamera_metadata_enum_android_lens_facing_t;
The problem is when I am trying to declare this enum as my class'es member the compiler can't find definition (header is found).
../../../../src/main/cpp/include/camera_manager.h:41:9: error: unknown type name 'acamera_metadata_enum_android_lens_facing_t'
acamera_metadata_enum_android_lens_facing_t facing;
This is my class header:
#ifndef DAVINCI_CAMERA_MANAGER_H
#define DAVINCI_CAMERA_MANAGER_H
#include <map>
#include <string>
#include <camera/NdkCameraManager.h>
#include <camera/NdkCameraError.h>
#include <camera/NdkCameraDevice.h>
#include <camera/NdkCameraMetadataTags.h> // The enumeration is defined here
#include <media/NdkImageReader.h>
namespace DaVinci {
class CameraId;
class CameraManager {
struct ACameraManager *_manager;
std::map<std::string, CameraId> _cameras;
std::string _activeCameraId;
int32_t _cameraFacing;
int32_t _cameraOrientation;
bool _valid;
public:
CameraManager();
~CameraManager();
};
// helper classes to hold enumerated camera
class CameraId {
public:
struct ACameraDevice *device;
std::string id;
acamera_metadata_enum_android_lens_facing_t facing;
bool available; // free to use ( no other apps are using
bool owner; // we are the owner of the camera
explicit CameraId(const char *id);
explicit CameraId();
};
};
#endif //DAVINCI_CAMERA_MANAGER_H
Where can the problem be?
P.S. I am using c++ 14 if it's important.
UPDATED
I created a repository with my project: https://bitbucket.org/ghostman2013/davinci_test
In your project's app/build.gradle you have minSdkVersion set to 21.
The native camera APIs were added in API level 24.
So you can either A) increase your minSdkVersion to 24 or higher, or B) Not use the native camera APIs in your library.
Related
I am hooking an existing library that is compiled using gnustl std::string instead of libc++ std::_ndk1::string. If I try to set or access these strings I just get garbage. How do I convert my std::string to std::_ndk1::string and vice versa in my hook application?
I cannot compile my hook with "-DANDROID_STL=gnustl_shared" because it no longer exists and other libraries in use require libc++.
The documentation mentions this https://developer.android.com/ndk/guides/cpp-support "The various STLs are not compatible with one another. As an example, the layout of std::string in libc++ is not the same as it is in gnustl" which is exactly the problem.
To use gnustl, you could compile all your native code with NDK r.17 or older. This is a dangerous path, because many important bugs, including security-related, have been fixed since then.
Another unsupported (and not recommended) way to deal with your problem is to get the gnustl sources from NDK r.17 and compile them with the latest NDK version.
Your best option is to have all your dependencies rebuilt with a recent version of NDK and its c++_shared runtime library.
Here's what I came up with (for now, really not ideal):
StringsProxy.cc
#include "StringsProxy.h"
#include <iostream>
#include <string>
using namespace std;
__attribute__((visibility("default")))
extern "C" StringsProxy::StringsProxy(const char* contents)
{
set_string = std::string(contents);
}
__attribute__((visibility("default")))
extern "C" StringsProxy::StringsProxy(uintptr_t str) {
set_string = *reinterpret_cast<proxy_string*>(str);
}
__attribute__((visibility("default")))
extern "C" const char* StringsProxy::c_str() {
return set_string.c_str();
}
__attribute__((visibility("default")))
extern "C" const uintptr_t* StringsProxy::ptr() {
return reinterpret_cast<uintptr_t *>(&set_string);
}
__attribute__((visibility("default")))
extern "C" StringsProxy::~StringsProxy() {
}
StringsProxy.h
#ifndef __STRINGSPROXY_H__
#define __STRINGSPROXY_H__
#include <string>
typedef std::basic_string<char> proxy_string;
class StringsProxy
{
public:
/* Initialize StringsProxy with a pointer to an existing string */
StringsProxy(uintptr_t str);
/* Initialize StringsProxy with a new string */
StringsProxy(const char* str);
/* Get C string */
virtual const char* c_str();
/* Get pointer to string for injection */
const virtual uintptr_t* ptr();
private:
proxy_string set_string;
};
#endif
Compile this into a shared object using the old NDK with -DCMAKE_ANDROID_STL_TYPE=gnustl_static
Then link this shared object to the hooking program (in CMakeLists):
target_link_libraries(${TARGET_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/abiproxy/build/armeabi-v7a/libabiproxy.so)
Then in the hooking program, can be used like this:
#include "abiproxy/StringsProxy.h"
void *setUriDebug(uintptr_t a1, uintptr_t stri) {
auto y = StringsProxy(stri);
LOGI("URI CALLED %s", y.c_str());
return setUriDebugOld(a1, stri);
}
Or in reverse:
StringsProxy assetNameBaseProxy = StringsProxy("https://example.com/");
void setResourceUrl(uintptr_t* a1, int a2) {
*(a1 + 1) = *assetNameBaseProxy.ptr();
}
This isn't by any means a good solution, but it works for my use-case.
I created C/C++ project in android studio and I want to use NDK camera.
I wrote in my cpp file
#include <camera/NdkCameraMetadata.h>
#include <camera/NdkCameraManager.h>
#include <camera/NdkCameraDevice.h>
#include <jni.h>
#include <string>
extern "C" JNIEXPORT jstring JNICALL
Java_com_example_test_MainActivity_listDevices(JNIEnv* env, jobject)
{
std::string text;
ACameraIdList *camList;
ACameraManager *camManager;
camManager = ACameraManager_create();
camera_status_t result = ACameraManager_getCameraIdList(camManager, &camList);
if (result == ACAMERA_OK)
{
text = "Error List devices";
}
else
{
text = "Device listed";
}
return env->NewStringUTF(text.c_str());;
}
but Android studio is writing
"Can't resolve type ACameraIdList"
What I'm doing wrong? I just added this code into .cpp file, nothing else. Idid not changed any other files.
As mentioned in the comments, you need to set the minSDK to 24 or higher.
The NdkCameraDevice.h header files detects the minSDK using the __ANDROID_API__ identifier:
#if __ANDROID_API__ >= 24
...
typedef struct ACameraIdList {
int numCameras; ///< Number of camera device Ids
const char** cameraIds; ///< list of camera device Ids
} ACameraIdList;
...
#endif
This means that if the minSDK is below 24 the C preprocessor will omit the declaration of ACameraIdList and other related structures and functions. This leads to the "Can't resolve type ACameraIdList" error.
I have Java classes being translated to Objective C (J2Objc using the cradle plugin). The simple Android app and Unit tests work fine. The same simple Objective C iOS app also works perfectly. However, when I try to write similar code in a Swift project I cannot access instance variables, find methods, etc. This is relatively new to me so I may be missing something basic.
Here's the code in Objective C. Works perfectly:
SHRRefreshAppointments *mTest = [[SHRRefreshAppointments alloc] initWithId:nil withBoolean:true];
[mTest run];
SHREventListResp *mResp = [SHREventListResp parseFromWithByteArray:mTest->mResponseData_];
NSLog(#"%#", mResp.description);
Same code in Swift - I cannot find the instance variable mResponseData which is readily available in Objective C:
let mTest : SHRRefreshAppointments = SHRRefreshAppointments(id: nil, withBoolean: true)
mTest.run()
var mResp : SHREventListResp = SHREventListResp.parseFromWithByteArray(mTest.)
Here are the contents of the bridging header:
#include "JreEmulation.h"
#include "J2ObjC_header.h"
#import "com/gcatconsult/shared/remote/AppConstants.h"
#import "com/gcatconsult/shared/remote/AppUtils.h"
#import "com/gcatconsult/shared/messages/nano/Resp.h"
#import "com/gcatconsult/shared/messages/nano//Req.h"
#import "com/gcatconsult/shared/messages/nano/EventListResp.h"
#import "com/gcatconsult/shared/messages/nano/EventListReq.h"
#import "com/gcatconsult/shared/messages/nano/Event.h"
#import "com/gcatconsult/shared/remote/RefreshAppointments.h"
#import "com/gcatconsult/shared/remote/NetworkBase.h"
SHRRefreshAppointments header:
//
// Generated by the J2ObjC translator. DO NOT EDIT!
// source: /Users/gabrielchoza/AndroidStudioProjects/GcatMobile/shared/src/main/java/com/gcatconsult/shared/remote/RefreshAppointments.java
//
#include "J2ObjC_header.h"
#pragma push_macro("INCLUDE_ALL_ComGcatconsultSharedRemoteRefreshAppointments")
#ifdef RESTRICT_ComGcatconsultSharedRemoteRefreshAppointments
#define INCLUDE_ALL_ComGcatconsultSharedRemoteRefreshAppointments 0
#else
#define INCLUDE_ALL_ComGcatconsultSharedRemoteRefreshAppointments 1
#endif
#undef RESTRICT_ComGcatconsultSharedRemoteRefreshAppointments
#if !defined (SHRRefreshAppointments_) && (INCLUDE_ALL_ComGcatconsultSharedRemoteRefreshAppointments || defined(INCLUDE_SHRRefreshAppointments))
#define SHRRefreshAppointments_
#define RESTRICT_ComGcatconsultSharedRemoteNetworkBase 1
#define INCLUDE_SHRNetworkBase 1
#include "com/gcatconsult/shared/remote/NetworkBase.h"
#define RESTRICT_JavaLangRunnable 1
#define INCLUDE_JavaLangRunnable 1
#include "java/lang/Runnable.h"
#interface SHRRefreshAppointments : SHRNetworkBase < JavaLangRunnable >
#pragma mark Public
- (instancetype)initWithId:(id)requestData
withBoolean:(jboolean)asyncCall;
#pragma mark Protected
- (void)postProcessExcecute;
#end
J2OBJC_EMPTY_STATIC_INIT(SHRRefreshAppointments)
FOUNDATION_EXPORT void SHRRefreshAppointments_initWithId_withBoolean_(SHRRefreshAppointments *self, id requestData, jboolean asyncCall);
FOUNDATION_EXPORT SHRRefreshAppointments *new_SHRRefreshAppointments_initWithId_withBoolean_(id requestData, jboolean asyncCall) NS_RETURNS_RETAINED;
FOUNDATION_EXPORT SHRRefreshAppointments *create_SHRRefreshAppointments_initWithId_withBoolean_(id requestData, jboolean asyncCall);
J2OBJC_TYPE_LITERAL_HEADER(SHRRefreshAppointments)
#compatibility_alias ComGcatconsultSharedRemoteRefreshAppointments SHRRefreshAppointments;
#endif
#pragma pop_macro("INCLUDE_ALL_ComGcatconsultSharedRemoteRefreshAppointments")
The SHRNetworkBase superclass:
//
// Generated by the J2ObjC translator. DO NOT EDIT!
// source: /Users/gabrielchoza/AndroidStudioProjects/GcatMobile/shared/src/main/java/com/gcatconsult/shared/remote/NetworkBase.java
//
#include "J2ObjC_header.h"
#pragma push_macro("INCLUDE_ALL_ComGcatconsultSharedRemoteNetworkBase")
#ifdef RESTRICT_ComGcatconsultSharedRemoteNetworkBase
#define INCLUDE_ALL_ComGcatconsultSharedRemoteNetworkBase 0
#else
#define INCLUDE_ALL_ComGcatconsultSharedRemoteNetworkBase 1
#endif
#undef RESTRICT_ComGcatconsultSharedRemoteNetworkBase
#if !defined (SHRNetworkBase_) && (INCLUDE_ALL_ComGcatconsultSharedRemoteNetworkBase || defined(INCLUDE_SHRNetworkBase))
#define SHRNetworkBase_
#define RESTRICT_JavaLangRunnable 1
#define INCLUDE_JavaLangRunnable 1
#include "java/lang/Runnable.h"
#class IOSByteArray;
#class JavaLangInteger;
#interface SHRNetworkBase : NSObject < JavaLangRunnable > {
#public
NSString *mGetPatientPath_;
NSString *mStringURL_;
IOSByteArray *mRequestData_;
IOSByteArray *mResponseData_;
jboolean mShouldCompress_;
jint mCurrentCall_;
jboolean mAsyncCall_;
}
#pragma mark Public
- (instancetype)initWithNSString:(NSString *)callPath
withBoolean:(jboolean)shouldCompress
withJavaLangInteger:(JavaLangInteger *)currentCall
withBoolean:(jboolean)async;
- (void)run;
#pragma mark Protected
- (void)postProcessExcecute;
- (id)sendAsyncServerRequestWithNSString:(NSString *)stringURL
withId:(id)requestData
withBoolean:(jboolean)shouldCompress
withJavaLangInteger:(JavaLangInteger *)currentCall;
#end
J2OBJC_EMPTY_STATIC_INIT(SHRNetworkBase)
J2OBJC_FIELD_SETTER(SHRNetworkBase, mGetPatientPath_, NSString *)
J2OBJC_FIELD_SETTER(SHRNetworkBase, mStringURL_, NSString *)
J2OBJC_FIELD_SETTER(SHRNetworkBase, mRequestData_, IOSByteArray *)
J2OBJC_FIELD_SETTER(SHRNetworkBase, mResponseData_, IOSByteArray *)
FOUNDATION_EXPORT void SHRNetworkBase_initWithNSString_withBoolean_withJavaLangInteger_withBoolean_(SHRNetworkBase *self, NSString *callPath, jboolean shouldCompress, JavaLangInteger *currentCall, jboolean async);
FOUNDATION_EXPORT SHRNetworkBase *new_SHRNetworkBase_initWithNSString_withBoolean_withJavaLangInteger_withBoolean_(NSString *callPath, jboolean shouldCompress, JavaLangInteger *currentCall, jboolean async) NS_RETURNS_RETAINED;
FOUNDATION_EXPORT SHRNetworkBase *create_SHRNetworkBase_initWithNSString_withBoolean_withJavaLangInteger_withBoolean_(NSString *callPath, jboolean shouldCompress, JavaLangInteger *currentCall, jboolean async);
J2OBJC_TYPE_LITERAL_HEADER(SHRNetworkBase)
#compatibility_alias ComGcatconsultSharedRemoteNetworkBase SHRNetworkBase;
#endif
#pragma pop_macro("INCLUDE_ALL_ComGcatconsultSharedRemoteNetworkBase")
Any help will be appreciated.
My limited understanding is that Swift imports Objective C properties as fields, not the fields themselves. You'll therefore need an accessor method for mResponseData.
The good news is that j2objc has a Property annotation, which you can add to the mResponseDate field so an equivalent Objective C property is generated during translation. That property should be imported later in Swift.
The Property annotation will also generate default accessors (like #synthesize does in Objective C), so if your Java class already has accessors, specify them using the getter= and setter= #property attributes. The translator's testProperties() test demonstrates a complex property annotation example.
mResponseData_ is an ivar and Swift can only access objective-c properties or functions. Alternative you can use mTest.valueForKey("mResponseData_") and mTest.setValue(someValue, forKey: "mResponseData_") or edit the generated class and transform the ivar in a property or method.
Not that you can create extension files with computed get and set to encapsulate the valueForKey implementation.
You can refer to this question for more details.
I am creating android application that uses libvlc to play a video.
Since vlc/libvlc doesnt have any kind of event/callback for subtitles i have created my own text renderer module in modules/text_rendere/spucallback
Module compiles, but i have two problems.:
I dont see any log messages from this module
How can i use this module from libvlc
callback.h
typedef void (*spu_cb_t)(text_segment_t *p_segment);
struct spu_cb_t {
spu_cb_t cb;
};
struct spu_cb_t *callback;
callback.c
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdlib.h>
/* VLC core API headers */
#include <vlc_common.h>
#include <vlc_plugin.h>
#include <vlc_interface.h>
#include <vlc_filter.h>
#include "callback.h"
static int Open(vlc_object_t *);
static void Close(vlc_object_t *);
static int RenderText(filter_t *,
subpicture_region_t *p_region_out,
subpicture_region_t *p_region_in,
const vlc_fourcc_t *p_chroma_list);
/* Module descriptor */
vlc_module_begin()
set_shortname(N_("SPU Callback "))
set_description(N_("SPU Callback module"))
set_capability("text renderer", 0)
set_callbacks(Open, Close)
set_category(CAT_VIDEO)
vlc_module_end ()
static int Open(vlc_object_t *p_this)
{
filter_t *p_filter = (filter_t *)p_this;
p_filter->pf_render = RenderText;
printf("spucallback:Open");
callback = (spu_cb_t*) malloc(sizeof(spu_cb_t));
if (!callback)
goto error;
return VLC_SUCCESS;
error:
free(callback);
return VLC_EGENERIC;
}
static void Close(vlc_object_t *p_this)
{
printf("spucallback:Close");
free(callback->cb);
free(callback);
}
static int RenderText(filter_t *p_filter,
subpicture_region_t *p_region_out,
subpicture_region_t *p_region_in,
const vlc_fourcc_t *p_chroma_list)
{
text_segment_t *p_segment = p_region_in->p_text;
callback->cb(p_segment);
printf("spucallback:RenderText");
return VLC_SUCCESS;
}
Code is not yet finished obviously
This log messages might be related:
[e41bfa2c] core spu text: looking for text renderer module matching "spucallback": 1 candidates
[e41bfa2c] core spu text: no suitable access module for `file:///vendor/etc/fallback_fonts.xml'
[e41bfa2c] core spu text: using text renderer module "freetype"
I did an Opencv's application en windows and now I am using JNI to convert this code to Android but I am having some problems.
In concrete my native code not do nothing.
This is my Java class where I define my native methods:
package com.example.telo3;
import org.opencv.core.Mat;
public class Process {
static {
System.loadLibrary("nativo");
}
public Process(){
dir=inicializar_nativo();
}
public void Procesar(Mat framedetect, Mat framedraw){
procesar_nativo(dir,framedetect.getNativeObjAddr(),framedraw.getNativeObjAddr());
}
private long dir;
private static native long inicializar_nativo();
private static native void procesar_nativo(long thiz, long framedetect, long framedraw);
}
This is my JNI code:
#include "nativo.h"
#include <opencv2/objdetect/objdetect.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include "opencv2/video/tracking.hpp"
#include <iostream>
#include <stdio.h>
#include "FaceDetector.h"
#include "Draw.h"
#include "Almacena.h"
#include "Runnable.h"
using namespace std;
using namespace cv;
#include <android/log.h>
#define LOG_TAG "NATIVO"
#define LOGD(...) ((void)__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__))
struct variables {
Almacena almacena;
Draw draw;
FaceDetector face_detector;
};
JNIEXPORT jlong JNICALL Java_com_example_telo3_Process_inicializar_1nativo(
JNIEnv *, jobject) {
long dir = (long) new variables();
return (dir);
}
JNIEXPORT void JNICALL Java_com_example_telo3_Process_procesar_1nativo(JNIEnv *,
jobject, jlong dir, jlong framedetect, jlong framedraw) {
Mat* telo =(Mat*)framedetect;
Mat* telo2= (Mat*)framedraw;
((variables*)dir)->almacena = ((variables*)dir)->face_detector.Detect(*telo);
//almacena = face_detector.Detect(frame_gray);
((variables*)dir)->draw.Dibujar(*telo2,((variables*)dir)->almacena);
//frame_capturado = draw.Dibujar(frame_capturado, almacena);
if( (((variables*)dir)->almacena.get_faces()).size() ==0){
LOGD("no detecto caras");
}
}
I think that I use the Jni correctly but the function Detect not works correctly because when I uses this if return 0.
Is framedetect 0? I made a test app based on this and it worked fine (that is, the jlong was converted to and from just fine, so that shouldn't be the issue).
Try catching the error with ndk-gdb to better understand the problem. Attaching it to the process might a problem though if it crashes straight away, in that case I like to put breakpoint on the java side before the crash, make the execution pause there using the debugger, attach ndk-gdb and continue let the java process continue.
Also I recommend using reinterpret_cast<jlong> and reinterpret_cast<variables*> instead of the C style casts, and save that cast to a separate variable to avoid casting all the time! cleaner code!