0

I am trying to connect a c method with a python script. I did it by using:

#include<stdio.h>
void pythonEx(){
system("pythonScript.py");
}

In this way I can run the python script but I don´t know how to pass data from the method to the python script.

6
  • 1
    Pass data how? Using command line? Commented Oct 27, 2016 at 14:31
  • 1
    Can't you just pass the data as arguments to the python script? Commented Oct 27, 2016 at 14:33
  • This link details a better approach to using python within a C program: linuxjournal.com/article/8497 Commented Oct 27, 2016 at 14:37
  • Can your Python script accept arguments? Commented Oct 27, 2016 at 14:51
  • 1
    Take a look here, where you can find sample project calling Python library from C code: github.com/mkopsnc/keplerhacks/tree/master/python Commented Oct 27, 2016 at 15:48

1 Answer 1

1

I suggest to go via JNI here.

First, you need JNI code that will call Python lib:

#include "jni.h"
#include "runscript27.h"
#include "python/Python.h"
#include <stdio.h>

static PyThreadState *tstate = NULL;
static PyGILState_STATE gstate = 0;

// Initialization should be done once
JNIEXPORT void JNICALL Java_python_Python_pyinitialize
  (JNIEnv *env, jclass obj) {

    Py_Initialize();

    // This is important!!
    // Remember to reserve PyGILState
    // It is not thread safe
    gstate = PyGILState_Ensure();
}

// Finalization should be done once
JNIEXPORT void JNICALL Java_python_Python_pyfinalize
  (JNIEnv *env, jclass obj) {

  // once finished remember to release GIL
  PyGILState_Release(gstate);

  Py_Finalize();

}

JNIEXPORT void JNICALL Java_python_Python_runstring27
  (JNIEnv *env, jclass obj, jstring str) {

  // we have to get string bytes into C string
  const char *c_str;
  c_str = (*env)->GetStringUTFChars(env, str, NULL);
  if(c_str == NULL) {
    return;
  }

  // Some info for the user
  printf("Script from python.Python: %s\n", c_str);

  PyRun_SimpleString( c_str );

  // after using it, remember to release the memory
  (*env)->ReleaseStringUTFChars(env, str, c_str);
}

JNIEXPORT void JNICALL Java_python_Python_runscript27
  (JNIEnv *env, jclass obj, jstring str, jstring name) {

  // we have to get string bytes into C string
  const char *c_str;
  c_str = (*env)->GetStringUTFChars(env, str, NULL);
  if(c_str == NULL) {
    return;
  }

  // we have to get string bytes into C string
  const char *c_name;
  c_name = (*env)->GetStringUTFChars(env, name, NULL);
  if(c_name == NULL) {
    return;
  }

  // Some info for the user
  printf("Script from python.Python: %s\n", c_name);
  printf("File with script: %s\n",c_str);

  // We will open file passed as argument
  // and call this script via Python library
  FILE* file;
  file = fopen(c_str,"r");

  PyRun_SimpleFile(file, c_str);

  // close file, clean up, and return. That's it.
  fclose(file);

  // after using it, remember to release the memory
  (*env)->ReleaseStringUTFChars(env, str, c_str);
  (*env)->ReleaseStringUTFChars(env, str, c_name);
}

Then, you can call this code from Java:

package python;

import java.io.*;

public class Python {
    static {
        System.loadLibrary("callpy27");
        Python.pyinitialize();
    }

    public static native void runscript27(String script, String name);
    public static native void runstring27(String script);
    public static native void pyinitialize();
    public static native void pyfinalize();

    public static void main(String [] arg) {
        // Super simple sctipt to call
        String script = "print 'Hello from python'";

        // run script from file
        try {
            PrintWriter writer = new PrintWriter("script.py", "UTF-8");
            writer.println(script);
            writer.flush();
            writer.close();

            pyinitialize();
            runscript27("script.py", "test");
            pyfinalize();
        } catch(Exception ex) {
            ex.printStackTrace();
        }

        // run script passed as string
        try {
            pyinitialize();
            runstring27( script );
            pyfinalize();
        } catch(Exception ex) {
            ex.printStackTrace();
        }
    }
}

For the full sample (with Makefile and sample code, take a look here: https://github.com/mkopsnc/keplerhacks/tree/master/python)

Sign up to request clarification or add additional context in comments.

4 Comments

Not good answer form. Answers should address the question with more than a simple link, Links can become unavailable at any time if the site they point to cease to exist. At least include a code snippet that addresses the question.
There is nothing wrong with the information you posted, it is useful and addresses question, just in a very temporary form. If you truly do not care about points, this would have fit better as a comment.
I'm not quite sure how an example of calling Python from Java relates to the question of how to call it from C. The part of the answer before the Java example seems useful (to OP), though.
You are right. I just used one of the samples where I make call from Java to Python via C. And, you are right, it could be simplified by stripping JNI stuff.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.