简体   繁体   中英

VS2015 cross-platform Android and C++

I'm using Visual Studio 2015 to do cross-platform development. I have existing C++ project and would like the android side to call it. I have read about JNI, but I use VS2015 instead.

So I'm able to call C++ non-member function, but how can I call member function like the function below Multiply() in my SharedObject1.h file.

class SharedObject1
{
public:
    const char * getPlatformABI();
    SharedObject1();
    ~SharedObject1();

    int Multiply(int a, int b);
};

in my SharedObject1.cpp file:

#include "SharedObject1.h"

#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "SharedObject1", __VA_ARGS__))
#define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, "SharedObject1", __VA_ARGS__))

extern "C" {
    /* This trivial function returns the platform ABI for which this dynamic native library is compiled.*/
    const char * SharedObject1::getPlatformABI()
    {
    #if defined(__arm__)
    #if defined(__ARM_ARCH_7A__)
    #if defined(__ARM_NEON__)
        #define ABI "armeabi-v7a/NEON"
    #else
        #define ABI "armeabi-v7a"
    #endif
    #else
        #define ABI "armeabi"
    #endif
    #elif defined(__i386__)
        #define ABI "x86"
    #else
        #define ABI "unknown"
    #endif
        LOGI("This dynamic shared library is compiled with ABI: %s", ABI);
        return "This native library is compiled with ABI: %s" ABI ".";
    }

    void SharedObject1()
    {
    }

    SharedObject1::SharedObject1()
    {
    }

    SharedObject1::~SharedObject1()
    {
    }

    int Add(int a, int b) 
    {
        return (a + b);
    }   

    int SharedObject1::Multiply(int a, int b)
    {
        return (a*b);
    }
}

So right now I can call function Add() from Android side in VS2015 after adding SharedObject1.so file to the project below then use DllImport:

using System;
using Android.App;
using Android.Content;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;
using System.Runtime.InteropServices;

namespace App1
{
    [Activity(Label = "App1", MainLauncher = true, Icon = "@drawable/icon")]
    public class MainActivity : Activity
    {
        int count = 1;

        [DllImport("SharedObject1.so")]
        public static extern int Add(int a, int b);

        [DllImport("SharedObject1.so")]
        public static extern int Multiply(int a, int b);

        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);

            // Set our view from the "main" layout resource
            SetContentView(Resource.Layout.Main);

            // Get our button from the layout resource,
            // and attach an event to it
            Button button = FindViewById<Button>(Resource.Id.MyButton);

            button.Click += delegate { button.Text = string.Format("{0} clicks!", count++); };

            try
            {

                EditText TV1 = FindViewById<EditText>(Resource.Id.editText1);
                int c1 = Add(4, 6);
                TV1.Text = c1.ToString();                    

                EditText TV2 = FindViewById<EditText>(Resource.Id.editText2);
                int c2 = Multiply(2, 50);
                TV2.Text = c2.ToString();  

            }
            catch (Exception Ex)
            {
                string msg = Ex.Message;
                throw;
            }
        }
    }
}

But i don't know how to call class member function, Multiply() because it always throws except "System.EntryPointNotFoundException: Multiply" after calling Multiply(). Can someone give me suggestion? thanks.

------Update the SharedObject1 class-------update(1)-----

#ifdef SHAREOBJECT_EXPORTS
    #define SHAREOBJECT_API __declspec(dllexport)
#else
    #define SHAREOBJECT_API __declspec(dllimport)
#endif

class SharedObject1
{
public:
    const char * getPlatformABI();
    SharedObject1();
    ~SharedObject1();

    int Multiply(int a, int b);
};

So how can i call this class member from android within VS2015 format?

------Update the SharedObject1 class------update(2)------

#ifdef SHAREOBJECT_EXPORTS
    #define SHAREOBJECT_API __declspec(dllexport)
#else
    #define SHAREOBJECT_API __declspec(dllimport)
#endif

class SharedObject1
{
public:
    const char * getPlatformABI();
    SharedObject1();
    ~SharedObject1();

    SharedObject1* getInstance()
    {
       SharedObject1* so = new SharedObject1();
       return so;
    }

    int Multiply(int a, int b);
    int Multiply_Obj(SharedObject* obj, int a, int b)
    {
        return obj->Multiply(a,b);
    }
};

What will be the caller look like for Multiply_Obj() and getInstance()?

Keep both files SharedObject1.h and SharedObject1.cpp the same as above and pull the update(1) and (2) into new project then the project source file adds the include "SharedObject1.h" so that should do it.

#include "TestMathFuncLib.h"
#include "SharedObject1.h"

#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "TestMathFuncLib", __VA_ARGS__))
#define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, "TestMathFuncLib", __VA_ARGS__))

extern "C" {
    /* This trivial function returns the platform ABI for which this dynamic native library is compiled.*/
    const char * TestMathFuncLib::getPlatformABI()
    {
    #if defined(__arm__)
    #if defined(__ARM_ARCH_7A__)
    #if defined(__ARM_NEON__)
        #define ABI "armeabi-v7a/NEON"
    #else
        #define ABI "armeabi-v7a"
    #endif
    #else
        #define ABI "armeabi"
    #endif
    #elif defined(__i386__)
        #define ABI "x86"
    #else
        #define ABI "unknown"
    #endif
        LOGI("This dynamic shared library is compiled with ABI: %s", ABI);
        return "This native library is compiled with ABI: %s" ABI ".";
    }

    void TestMathFuncLib()
    {
    }

    TestMathFuncLib::TestMathFuncLib()
    {
    }

    TestMathFuncLib::~TestMathFuncLib()
    {
    }

    SharedObject1* CreateTestClass()
    {
        return new SharedObject1();
    }


    void DisposeTestClass(SharedObject1* pObject)
    {
        if (pObject != NULL)
        {
            delete pObject;
            pObject = NULL;
        }
    }


    int TestMultiply(SharedObject1* pObject, int a, int b)
    {
        return pObject->Multiply(a, b);
    }
}

Now on the android side, just call CreateTestClass() using DllImport, then passing that object into TestMultiply(obj, int, int); it should work.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM