I've just installed the NDK onto Eclipse, but I'm having some trouble with something..
Here's the code:
#include <jni.h>
#include <stdlib.h>
#include <stdio.h>
void deleteFile(const char *fileName) {
remove(fileName);
}
void writeFile(const char *fileName, byte array) {
}
But something is going wrong.. I got this error:
jni/[projectName].cpp:9:38: error: 'byte' has not been declared
byte couldn't be resolved! which is a big problem because I absolutely need that type.. I have to use it to write data into a file!
I've followed a lot of tutorials, I also tried to import all of my MinGW libraries with no success.
byte isn't a standard C or C++ type ... It may be a typedef in a non-standard header file. Where have you seen code with that type ? May be you would like to use const unsigned char * ?
I know that Visual Studio define BYTE type:
typedef unsigned char BYTE; // 8-bit unsigned entity.
typedef BYTE * PBYTE; // Pointer to BYTE.
But this is not standard. And it is "BYTE", not "byte".
'byte' doesn't exist in standard C or C++, if all your code depends on , use 'jbyte' instead, it is defined in this header, and maps to an 8-bit unsigned integer type.
Alternatively, you could define 'byte' with a typedef as in:
typedef unsigned char byte;
And ensure this is used/parsed by all your sources (e.g. put it in a shared header).
A slightly more correct way to do it is:
#include <inttypes.h>
typedef uint8_t byte;
It will be equivalent on all supported Android platforms, but requires an additional include.
(Technically, 'char' can be more than 8 bits on some really odd platforms, but none of them are ever going to be targetted by Android).
Related
First off, my app has a file named Android.hpp. This is part of the tmxlite library. Compiling tmxlite on windows works fine. However, when I move the code to android studio and compile it (with the NDK), I get an error.
Android.hpp:
/*********************************************************************
Matt Marchant 2016
http://trederia.blogspot.com
tmxlite - Zlib license.
This software is provided 'as-is', without any express or
implied warranty. In no event will the authors be held
liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute
it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented;
you must not claim that you wrote the original software.
If you use this software in a product, an acknowledgment
in the product documentation would be appreciated but
is not required.
2. Altered source versions must be plainly marked as such,
and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any
source distribution.
*********************************************************************/
#ifndef ANDROID_INC_HPP_
#define ANDROID_INC_HPP_
#ifdef __ANDROID__
#include <string>
#include <sstream>
#include <cstdlib>
namespace std
{
template <typename T>
std::string to_string(T value)
{
std::ostringstream os;
os << value;
return os.str();
}
}
#define STOI(str) std::strtol(str.c_str(), 0, 10)
#else
#define STOI(str) std::stoi(str)
#endif // __ANDROID__
#endif // ANDROID_INC_HPP_
The error:
In file included from E:\max\android_libs\tmxliteOG\tmxlite\src\FreeFuncs.cpp:28:
In file included from E:\max\android_libs\tmxliteOG\tmxlite\include\tmxlite\FreeFuncs.hpp:54:
E:\max\android_libs\tmxliteOG\tmxlite\include\tmxlite\detail\Android.hpp:37:11: error: expected '{'
Why is this happening? I was under the impression that this was how namespaces were supposed to be declared and I don't see what is wrong with it. I mean, I didn't even write the code :-).
help is greatly appreciated.
Objective
To generate the hash of a image file. I am using pHash library for this task. pHash library has below method used for generating the image hash.
int ph_dct_imagehash(const char* file,ulong64 &hash);
Datatype ulong64 is not present in android stdint.h. Due to which I am getting "cannot resolve type ulong64" error.
Please help how I can use ulong64 in c file in Android.
Can I use some third party library for this task?
Do we have any way around to fix this error?
This type is specific to pHash, and it is defined inside pHash.h by the following snippet:
#if defined( _MSC_VER) || defined(_BORLANDC_)
typedef unsigned _uint64 ulong64;
typedef signed _int64 long64;
#else
typedef unsigned long long ulong64;
typedef signed long long long64;
#endif
To use this type, just #include <pHash.h>.
I searched online and on this site and found this link which asks the same question I am about to, but the reply does not seem address the question. Plus one of the referenced links are missing. Basically the question is how do you efficiently and intelligently decide when to use a jni-compatible function to what you have in your C source file. I am familiar with what javah command does, but that command converts JAVA methods into a C header file to be used. What about the methods that are already implemented in a C source file? How can you know if you have to convert them to a JNI version of the method? I am using Android Studio and put in the following code in the .c source file that is in my jni folder of the project:
#include "com_example_sansari_usetbt_MainActivity.h"
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <android/log.h>
#define TAG "native-log-tag"
#define LOGI(LOG_TAG, ...) __android_log_print (ANDROID_LOG_INFO, TAG, __VA_ARGS__)
#define LOGV(LOG_TAG, ...) __android_log_print (ANDROID_LOG_VERBOSE, TAG, __VA_ARGS__)
#define LOGE(LOG_TAG, ...) __android_log_print (ANDROID_LOG_ERROR, TAG, __VA_ARGS__)
/*
* Class: com_example_sansari_usetbt_MainActivity
* Method: usetbt
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_example_sansari_useqsee_MainActivity_Usetbt
(JNIEnv *env, jobject obj)
{
int fd;
int rc = 0;
char *rd_buf[16];
//(*env)->printf("<1>%s: entered\n", argv[0]);
printf("<1>: entered\n");
fd = open("/dev/tbt", O_RDWR);
LOGI(LOG_TAG,"This is a log test");
LOGV(LOG_TAG,"This is a log test");
LOGE(LOG_TAG,"This is a log test");
//(*env)->fd;
//return;
if ( fd == -1 ) {
perror("<1>open failed");
rc = fd;
}
printf("<1>: open: successful\n");
/* Issue a read */
rc = read(fd, rd_buf, 0);
//I need to find what fd is and then use command completion to pick a jni finction. rd-buf seems to be jstring, and 0 seems to be int
rc = (*env)->GetString
if ( rc == -1 ) {
perror("<1>read failed");
close(fd);
}
printf("<1>: read: returning %d bytes!\n",rc);
close(fd);
(*env)->NewStringUTF(env,"Hi From Usetbt version 2");
}
And ndk-build compiles the project, but I do not get the result I am looking for. That is, the normal C version of the code which I compiled with NDK opens the driver and is able to interface with it, but this does not do the same. I do not see the result of the print statement in the kernel logs that is. I am not asking for someone to convert the above code; rather show me the way to know which of the above lines need to be converted, and what is the best way to do it please. I have read a number of items about this, and I am quickly coming up to speed, but if you can describe at a high level how
this conversion is done, please advise. I do have a copy of Java Native Interface and a number of Android texts and am going through them as fast as possible.
Thanks
I believe you need to call fflush(stdout); after your printf. As per this answer.
I'm writing an Adroid app with some C++ code behind the UI using Eclipse + NDK (r8d). I have some code that I thought was fool proof but the compiler just gives me weird errors like "Invalid arguments" without specifics. Here is what my C++ code looks like:
#include <jni.h>
#include <string>
using namespace std;
#include "../../Evaluator.Engine/Evaluator.Engine.h"
Evaluator evaluator;
extern "C" {
JNIEXPORT jstring JNICALL Java_haskellevaluator_android_MainActivity_evaluateNative(JNIEnv *env, jobject, jstring jInput)
{
...
string sInput(L"Hello world");
string sResult = evaluator.evaluate(sInput);
jstring jResult = env->NewStringUTF(sResult.data());
return jResult;
}
}
Evaluator.Engine.h is nothing fancy, but just a declaration of the class Evaluator.
#include <string>
using namespace std;
class Evaluator
{
public:
string evaluate(string input);
};
However, the compiler complains:
Invalid arguments '
Candidates are:
? evaluate(?)
'
as if string is not defined. But if I put a copy of the header file under the same folder, the error goes away. This is a Windows box. I have tried using \ and escaped \\ as path separators and it didn't work.
Does this sound like a NDK (or whatever the preprocessor it uses) bug? I don't want to move the header file because it'll be shared by other projects. I also hate to keep 2 copies of the same file.
Any ideas? Thanks.
Sorry I don't have windows OS, but I've tried you code on a MacOS, but it doesn't work because of:
string sInput(L"Hello world");
Saying that wchar_t cannot be put on std::string. Is it possible to be the same problem ?
I like to build the Android NDK example "native-audio", supplied with the NDK.
The NDK-supplied compiler swallows it without complaint, but Eclipse is showing several errors in file native-audio-jni.c.
In the code excerpt below, all of the static variable declarations have red underlining, because Eclipse claims that the types cannot be resolved. They are defined right up there in the OpenSLES.h file, which Eclipse does find if I Ctrl + left click the file.
Note that I modified the lines where hello_clip and android_clip are included compared to the example source - I put the array declarations in those "header" files also (they contained just comma separated data), since Eclipse had a problem parsing the syntax, too:
static const char array[] = #include"blah.h";
I tried things suggested over the internet, like starting with eclipse.exe -clean, clean project / rebuild, refresh project, etc., none helps.
So, what could be the reason/solution for Eclipse not resolving those types?
#include <assert.h>
#include <jni.h>
#include <string.h>
// for __android_log_print(ANDROID_LOG_INFO, "YourApp", "formatted message");
// #include <android/log.h>
// for native audio
#include <SLES/OpenSLES.h>
#include <SLES/OpenSLES_Android.h>
// for native asset manager
#include <sys/types.h>
#include <android/asset_manager.h>
#include <android/asset_manager_jni.h>
// pre-recorded sound clips, both are 8 kHz mono 16-bit signed little endian
// includes data arrays here
#include "hello_clip.h"
#include "android_clip.h"
// engine interfaces
static SLObjectItf engineObject = NULL;
static SLEngineItf engineEngine;
// output mix interfaces
static SLObjectItf outputMixObject = NULL;
static SLEnvironmentalReverbItf outputMixEnvironmentalReverb = NULL;
(the file is full of many more of those problems)