Issue
My return char function is not working. Others working fine, can someone help me with how to get string from C function as return value?
I've tried to search for it, but couldn't found solution.
This is my cpp code
#include <android/log.h>
#include <stdio.h>
#include <string.h>
using namespace std;
extern "C" void bar_init ()
{
__android_log_print (ANDROID_LOG_INFO, "*jonp*", "bar_init");
}
extern "C" int getMyName(int recept){
return recept;
}
extern "C" void PrintMyString(char const * chars){
__android_log_print (ANDROID_LOG_INFO, "*jonp*", chars);
}
extern "C" char* ReturnMyChar (char *chars){
strcpy( chars, "INSERT INTO test (nazwa, liczba) VALUES ('nowy wpis', '')");
__android_log_print (ANDROID_LOG_INFO, "*jonp*", chars);
return chars;
}
And my C# code
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 NativeTest
{
[Activity (Label = "NativeTest", MainLauncher = true, Icon = "@drawable/icon")]
public class MainActivity : Activity
{
[DllImport ("bar.so")]
static extern void bar_init();
[DllImport ("bar.so")]
static extern int getMyName(int test);
[DllImport ("bar.so")]
static extern void PrintMyString (string myname);
[DllImport ("bar.so")]
static extern string ReturnMyChar(string mychar);
int count = 1;
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
// Set our view from the "main" layout resource
SetContentView (Resource.Layout.Main);
Console.WriteLine ("PREPARING");
bar_init ();
int mybytes = getMyName (10);
PrintMyString ("Hello World");
Console.WriteLine ("WORKING:{0}",mybytes);
//string myValue = "hello";
string bytes = ReturnMyChar ("h");
//Console.WriteLine (myValue);
// 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++);
};
}
static byte[] GetBytes(string str)
{
byte[] bytes = new byte[str.Length * sizeof(char)];
System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
return bytes;
}
static string GetString(byte[] bytes)
{
char[] chars = new char[bytes.Length / sizeof(char)];
System.Buffer.BlockCopy(bytes, 0, chars, 0, bytes.Length);
return new string(chars);
}
}
}
This is my log :
[Resources] Preloaded drawable resource #0x1080093 (android:drawable/sym_def_app_icon) that varies with configuration!!
[Mono] DllImport attempting to load: '/system/lib/liblog.so'.
[Mono] DllImport loaded library '/system/lib/liblog.so'.
[Mono] DllImport searching in: '/system/lib/liblog.so' ('/system/lib/liblog.so').
[Mono] Searching for '__android_log_print'.
[Mono] Probing '__android_log_print'.
[Mono] Found as '__android_log_print'.
PREPARING
[*jonp*] bar_init
[*jonp*] Hello World
WORKING:10
[*jonp*] INSERT INTO test (nazwa, liczba) VALUES ('nowy wpis', '')
[libc] invalid address or address of corrupt block 0xb7a8eee8 passed to dlfree
[mono-rt] Stacktrace:
[mono-rt]
[mono-rt] at <unknown> <0xffffffff>
Found solution
C code
extern "C" char* ReturnMyChar (){
int len=strlen("INSERT INTO test (nazwa, liczba) VALUES ('nowy wpis', '')")+1;
char *chars=(char*) malloc(len);
memset(chars,0,len);
strcpy( chars, "INSERT INTO test (nazwa, liczba) VALUES ('nowy wpis', '')");
__android_log_print (ANDROID_LOG_INFO, "*jonp*", chars);
return chars;
}
C# code
[DllImport ("bar.so")]
static extern IntPtr ReturnMyChar();
.....
IntPtr bytes = ReturnMyChar ();
Console.WriteLine ("result string :"+Marshal.PtrToStringAuto(bytes));
Solution
As per my assumption you are in trouble because of modifying string literal in C.
from your C# code you have called
string bytes = ReturnMyChar ("h");
And in C you have receive function
extern "C" char* ReturnMyChar (char *chars){..}
So here argument becomes char *chars="h" which is constant string and compiler put it in read only memory. So modifying it cause Undefined behaviour. here
strcpy( chars, "INSERT INTO test (nazwa, liczba) VALUES ('nowy wpis', '')");
you have write data in string literal which cause you issues.
Now to overcome this you have to allocate memory in function and return that char array.
Also strcpy overwrite your previous buffer with current one. So there is no meaning of passing string in function.
string bytes = ReturnMyChar ("h");//OP can you tell me
// what is purpose of passing "h"?
Solution but without testing
In C code
extern "C" char* ReturnMyChar ()
{
int len=strlen("INSERT INTO test (nazwa, liczba) VALUES ('nowy wpis', '')")+1;
char *chars=malloc(len);
memset(chars,0,len);
strcpy( chars, "INSERT INTO test (nazwa, liczba) VALUES ('nowy wpis', '')");
__android_log_print (ANDROID_LOG_INFO, "*jonp*", chars);
return chars;
}
And from C# you can call like
string bytes = ReturnMyChar ();
Answered By - Jayesh Bhoi
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.