Git Product home page Git Product logo

cordova-plugin-hello-c's Introduction

cordova-plugin-hello-c

A simple example of a Cordova plugin that uses pure C code.

It illustrates how to use platform-specific (either Android or iOS) C code and how to share C code cross-platform (between Android and iOS).

For Android it utilizes the Android NDK to compile architecture-specific libraries and a JNI wrapper to expose the C functions to the Java plugin API.

For iOS it uses the pure C source code in place alongside the Objective-C plugin wrapper, as well as an example cross-platform library compiled as a static library for iOS.

usage example

  • Clone the test project
  • Add Android and iOS platforms: cordova platform add android && cordova platform add ios
  • Run: cordova run android / cordova run ios

Plugin structure

  • plugin.xml - Specifies the plugin's source files and libraries to copy to the platforms of the Cordova project into which the plugin is installed
  • compile-android and compile-android.cmd - Script to recompile C source code as a shared library for use with Android platform
  • compile-ios - Script to recompile cross-platform C library as static library for use with iOS platform
  • src/ - C source code and build scripts
    • common/ - cross-platform C source code to run on both Android and iOS
      • mylib/ - example cross-platform C library
    • android/ - source code and build scripts for Android platform
      • build-extras.gradle - Gradle build script to link up the NDK make file for debugging C code in Android Studio
      • HelloCPlugin.java - Provides the native Java implementation for Android of the Cordova plugin
      • HelloCJni.java - Provides the Java interface to the underlying JNI C implementation
        • jni/ - JNI C implementation and build script
          • HelloJni.c - C implementation of the JNI interface defined by HelloCJni.java, including
            • Android-specific implementation to get current CPU architecture
            • interfaces to cross-platform C functionality
          • Android.mk - NDK Make script to build the C source code into architecture-specific shared libraries
        • libs/ - contains folders for the various architecture-specific shared libraries built by the NDK Make script
    • ios/ - source code and build scripts for iOS platform
      • c_getArch.c & c_getArch.h - iOS-specific implementation to get current CPU architecture
      • HelloCPlugin.c & HelloCPlugin.h - Provides the native Objective-C implementation for iOS of the Cordova plugin
      • ios_compile.sh - Script to compile the cross-platform example library in src/common/mylib/ as a static library
      • Makefile - Make script invoked by the above script to perform the C compilation.
      • libs/ - the compiled cross-platform library
        • libmylib.a - the compiled cross-platform library as a multi-architecture static library
        • headers/ - the header files of the cross-platform library (static libraries require the headers externally)

Recompiling libraries

If you modify the C source files, be sure to re-build the compiled libraries.

Android

You can re-build the libhelloc.so binaries using the ndk-build script.

To do so:

  • Install Android NDK as instructed here
  • Add the NDK install path to your path environment variable
    • By default it's installed under $ANDROID_SDK_HOME/ndk-bundle
    • e.g. export PATH=$PATH;$ANDROID_SDK_HOME/ndk-bundle
  • Set the ANDROID_NDK_HOME environment variable to your NDK install path
    • e.g. export ANDROID_NDK_HOME=$ANDROID_SDK_HOME/ndk-bundle
  • Open terminal in plugin root folder
  • Run ./compile-android (compile-android.cmd on Windows)

If you are editing the C source code of the plugin in place in the example project:

  • Modify the C source in plugins/cordova-plugin-hello-c/src/android/jni or plugins/cordova-plugin-hello-c/src/common
  • Open terminal in plugins/cordova-plugin-hello-c
  • Delete src/android/libs and src/android/obj
  • Run compile-android (compile-android.cmd on Windows)
  • From the project root, remove and re-add the android platform to apply the plugin changes to the project cordova platform rm android && cordova platform add android

iOS

If you modify the C source code in common/mylib/ you'll need to rebuild the static library and headers in src/ios/libs.

  • Open terminal in plugin root folder
  • Run ./compile-ios

If you are editing the C source code of the plugin in place in the example project:

  • Modify the C source in plugins/cordova-plugin-hello-c/src/ios/ or plugins/cordova-plugin-hello-c/src/common
  • Open terminal in plugins/cordova-plugin-hello-c
  • Run ./compile-ios
  • From the project root, remove and re-add the platform to apply the plugin changes to the project cordova platform rm ios && cordova platform add ios

Debugging C source code

Android

  • The Android NDK enables C/C++ source code to be debugged in Android Studio alongside Java.
  • To do so, the source code must be included but not the compiled libraries.
  • To debug this plugin in Android Studio do the following:
    • Edit plugin.xml and in the <platform name="android"> block, comment out the source-file lines in the PRODUCTION block which include the compiled libraries
    • Remove/re-add the plugin or Android platform in your project to update the plugin files in the platform project
    • Open the Android platform project (platforms/android) in Android Studio
    • Connect an Android device for debugging
    • Use the Project Explorer to find and open one of the .c source files
    • Place a breakpoint, for example on a return statement
    • Select "Run" > "Debug ..." from the menu

iOS

  • Since iOS is a C-based platform, C debugging is inherently supported in the Xcode IDE
  • However, to debug the C code in the static library src/ios/libs/libmylib.a, you'll need to comment out the library files and comment in the source code for it:
  • Edit plugin.xml and in the <platform name="ios"> block
    • comment out the lines in the PRODUCTION block which include the compiled library and headers.
    • comment in the the commented-out lines in the DEBUG block which will include the uncompiled C source code for the library
  • Remove/re-add the plugin or iOS platform in your project to update the plugin files in the platform project
  • Use the OSX Finder to browse to platforms/ios/ in your Cordova project and double-click the .xcodeproj file to open it in Xcode.

cordova-plugin-hello-c's People

Contributors

angelskieglazki avatar clement360 avatar dflourusso avatar domq avatar don avatar dpa99c avatar edewit avatar jamesingham avatar kellycampbell avatar luisdemarchi avatar marceloboth avatar partus avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

cordova-plugin-hello-c's Issues

How can I use structs?

Hi,

I'm trying to use my C code and works fine, but when I have to call a function that takes Structs as input and/or output, I don't know how to send the information in JS. Example:

** .h File **

struct input_example {
    struct other_struct othStruct;
    struct internal_struct internalStruct;
    struct stores_external_Struct externalStruct[3];
    char path[200];
    char file [20];
    char database[200];
    int id;
};
struct output_example {
    int id;
    char somechar[100];
    int limitIntegers[15];
    float somefloat;
};

** .C File **

#include "file.h"
long calc_example(struct input_example *input, struct output_example *output)
{
 .... all code ....
}

** ..js File **

/*global cordova, module*/
module.exports = {
    calc_example: function(STRUCT ,successCallback, errorCallback) {
        cordova.exec(successCallback, errorCallback, "HelloCPlugin", "calc_example", [STRUCT]);
    },

How to call a function with input sctructs directly from JS file?

I don't know how to pass parameters as struct values in JS file. May be as an Array, multi-array?

Thank you!

Error initializing Cordova: Class not found

When I run my Ionic project with this plugin, after the launch on the device appears an alert that says:

Error initializing Cordova: Class not found

How can i fix this problem?

Processing Raw Data in C

Hi Dave,

I have been looking at your example of a cordova compiler for C via a Cordova plugin. This is new territory for me so please bear with my ignorance on this subject.

I have a question that I hope you might be able to answer: I have a unique challenge in that I want to process some raw data received on my phone via bluetooth, but the processing algorithm is written in C. Based on your example, I'm not sure whether it is possible to do this without somehow importing the data directly into the C code.

Am I mistaken? Would it be possible to import the raw data into my Ionic app and have it processed by something similar to your plugin and then have the output available to my app?

My thanks in advance.

Class Not Found

I downloaded the plugin and run it on the test project. However, when I run it on my emulator I had class not found ! (and I hadn't changed the C code yet!)
android version: 8.0.0
Cordova version: 9.0.0 ([email protected])
Capture

iOS 10 is the maximum deployment target for 32-bit targets

Hi,

I'm getting this error every time I run ./compile-ios:
clang: error: invalid iOS deployment version '-miphoneos-version-min=13.5', iOS 10 is the maximum deployment target for 32-bit targets [-Winvalid-ios-deployment-target]

Do you any idea?

cordova platform 7.x problems

hello,
I'm trying to make the test project work (cordova-plugin-hello-c) with [email protected] but I get this error:

cordova run android
cp: copyFileSync: could not write to dest file (code=ENOENT):/home/xxx/workspace/cordova-wrapper-c/platforms/android/res/xml/config.xml

Error: Unhandled error. (Parsing /home/xxx/workspace/cordova-wrapper-c/platforms/android/res/xml/config.xml failed)

I think the problem is that this plugin does not support [email protected]. How can I integrate it into my project with [email protected]?

Failed to restore plugin

Hello, after downloading the test-project and executing "cordova platform add android" I get this Error.

screenshot 1

Any idea how to fix this?

thx

Problems when run on cordova-android@7

hi,
I'm trying to make the test project work with [email protected] but when I run on Android device, the test app starts but outputs only deviceready.
In the Android Studio Logcat this warn comes back:

Rejecting re-init on previously-failed class java.lang.Class<com.example.HelloCJni>: java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/io.cordova.hellocordova-uUJEPTqhZpGH28gw-fLRPg==/base.apk"],nativeLibraryDirectories=[/data/app/io.cordova.hellocordova-uUJEPTqhZpGH28gw-fLRPg==/lib/arm64, /system/lib64, /system/vendor/lib64]]] couldn't find "libhelloc.so"
java.lang.NoClassDefFoundError: com.example.HelloCJni
at com.example.HelloCJni.calculate(Native Method)
at com.example.HelloCPlugin.execute(HelloCPlugin.java:35)
at org.apache.cordova.CordovaPlugin.execute(CordovaPlugin.java:98)
at org.apache.cordova.PluginManager.exec(PluginManager.java:132)
at org.apache.cordova.CordovaBridge.jsExec(CordovaBridge.java:59)
at org.apache.cordova.engine.SystemExposedJsApi.exec(SystemExposedJsApi.java:41)
at android.os.MessageQueue.nativePollOnce(Native Method)
at android.os.MessageQueue.next(MessageQueue.java:325)
at android.os.Looper.loop(Looper.java:142)
at android.os.HandlerThread.run(HandlerThread.java:65)
Caused by: java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/io.cordova.hellocordova-uUJEPTqhZpGH28gw-fLRPg==/base.apk"],nativeLibraryDirectories=[/data/app/io.cordova.hellocordova-uUJEPTqhZpGH28gw-fLRPg==/lib/arm64, /system/lib64, /system/vendor/lib64]]] couldn't find "libhelloc.so"
at java.lang.Runtime.loadLibrary0(Runtime.java:1011)
at java.lang.System.loadLibrary(System.java:1657)
at com.example.HelloCJni.(HelloCJni.java:12)
at com.example.HelloCJni.getArch(Native Method)
at com.example.HelloCPlugin.execute(HelloCPlugin.java:28)

I do not know if this is the problem but before the support at cordova-android@7, the test app worked with cordova-platform@6.

Thanks

Help C++

So, how can i send strings from JS to JAVA and JAVA to C++ Libraries. The C++ libraries too return the strings to JS to answer the user ?

Because the files do not work.

To send the strings from JS :
loadfileae.myLoad("string1", "string2", "string3", function(msg){
alert(msg);

},function(err){
alert(err);
});

Plugin JS :
module.exports = {
myLoad: function (setData1,setData2,setData3, successCallback, errorCallback) {
cordova.exec(successCallback, errorCallback, "LoadFileAe", "myLoad", [setData1, setData2, setData3]);
}
};

JAVA 1 :
package com.ae.plugin;

import org.apache.cordova.*;
import org.json.JSONArray;
import org.json.JSONException;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;

public class LoadFileAe extends CordovaPlugin {

protected static final String TAG = "LoadFile Plugin";
protected CallbackContext context;

@OverRide
public boolean execute(String action, JSONArray data, CallbackContext callbackContext) throws JSONException {
context = callbackContext;
boolean result = true;

try {
if (action.equals("myLoad")) {
String setData1 = data.getString(0);
String setData2 = data.getString(1);
String setData3 = data.getString(2);
String jniOutput = LoadFileAeJni.stringFromJNI(setData1, setData2, setData3);
String output = jniOutput;
callbackContext.success(output);

}else{
handleError("Invalid loader file !");
result = false;
}
} catch (Exception e) {
handleException(e);
result = false;
}
return result;
}

private void handleError(String errorMsg) {
try {
Log.e(TAG, errorMsg);
context.error(errorMsg);
} catch (Exception e) {
Log.e(TAG, e.toString());
}
}

private void handleException(Exception exception) {
handleError(exception.toString());
}

}

JAVA 2 :
package com.ae.plugin;

import android.app.Activity;
import android.widget.TextView;
import android.os.Bundle;

public class LoadFileAeJni {

public static native String stringFromJNI(String setData1, String setData2, String setData3);
static {
System.loadLibrary("loadfileae-jni");
}
}

C++ :
#include <string.h>
#include <jni.h>

using namespace std;

JNIEXPORT jstring JNICALL Java_com_ae_plugin_LoadFileAeJni_stringFromJNI
(JNIEnv *env,jobject thisObj, jstring getData1, jstring getData2, jstring getData3){

const char *fichier = env->GetStringUTFChars(getData1, NULL);
const char *uuid = env->GetStringUTFChars(getData2, NULL);
const string *extention = env->GetStringUTFChars(getData3, NULL);

if (fichier == NULL){
fichier="Aucun fichier detecté !";
}
if (uuid == NULL){
uuid="Aucune clé detecté !";
}
if (extention == NULL){
extention="Aucune extention detecté !";
}

env->ReleaseStringUTFChars(getData1, fichier);
env->ReleaseStringUTFChars(getData2, uuid);
env->ReleaseStringUTFChars(getData3, extention);

char resultat[999];
cout << "K7Player C++ Response : " << fichier << "Uuid : " << uuid << "Extention : " << extention << endl;
cin >> resultat;

return env->NewStringUTF(resultat.c_str());
}

compile-android problem

Hello,
I'm editing the files .c and .h in the /src/common/ but when I go to run compile-android it just generates the .so for arm64-v8a, armeabi-v7a, x86 and x86_64 architectures, omitting armeabi, mips and mips64.
This is the output:

./compile-android
Android NDK: APP_PLATFORM not set. Defaulting to minimum supported version android-14.
[arm64-v8a] Compile : helloc <= hello.c
[arm64-v8a] Compile : helloc <= mycomponent.c
[arm64-v8a] Compile : helloc <= mylib.c
[arm64-v8a] Compile : helloc <= mypart.c
[arm64-v8a] SharedLibrary : libhelloc.so
[arm64-v8a] Install : libhelloc.so => libs/arm64-v8a/libhelloc.so
[armeabi-v7a] Compile thumb : helloc <= hello.c
[armeabi-v7a] Compile thumb : helloc <= mycomponent.c
[armeabi-v7a] Compile thumb : helloc <= mylib.c
[armeabi-v7a] Compile thumb : helloc <= mypart.c
[armeabi-v7a] SharedLibrary : libhelloc.so
[armeabi-v7a] Install : libhelloc.so => libs/armeabi-v7a/libhelloc.so
[x86] Compile : helloc <= hello.c
[x86] Compile : helloc <= mycomponent.c
[x86] Compile : helloc <= mylib.c
[x86] Compile : helloc <= mypart.c
[x86] SharedLibrary : libhelloc.so
[x86] Install : libhelloc.so => libs/x86/libhelloc.so
[x86_64] Compile : helloc <= hello.c
[x86_64] Compile : helloc <= mycomponent.c
[x86_64] Compile : helloc <= mylib.c
[x86_64] Compile : helloc <= mypart.c
[x86_64] SharedLibrary : libhelloc.so
[x86_64] Install : libhelloc.so => libs/x86_64/libhelloc.so

Once the lib.so is generated, I remove the android platform, re-add it and I get this error back

workspace/cordova-plugin-hello-c-test/plugins/cordova-plugin-hello-c/src/android/libs/armeabi/libhelloc.so" not found!

How do I generate the missing architectures? is my flow wrong?
 
Thanks

Android.mk not found

Hello,

now i get this error while trying to "cordova platform add android".
screenshot 6

have you changed something?

compile-android.cmd error

Hello, when I execute the "compile-android.cmd" i get the following error.
screenshot 5
Would be great if somebody could help me.

Dlib Library

Hello,

do you think it is possible to get the Dlib library working with your code?

thx

Help Needed

How do we include custom CFLAGS in the below makefile

SRC=$(wildcard $(SRC_PATH)/*.c)
OBJS=$(patsubst %.c,%.o,$(SRC))

LDLIBS=$(patsubst %, $(TARGET_PATH)/lib%.a, $(DEPS))

all:$(ARCH)-$(LIBNAME).a

$(ARCH)-$(LIBNAME).a: $(OBJS)
@echo $(LDLIBS) $(OBJS)
$(AR) rcs $@ $(OBJS)
ranlib $@

clean:
rm $(OBJS)

.PHONY: realclean
realclean: clean
rm *.a

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.