如何使用JNI从JAVA调用带有C ++参数的函数?

时间:2015-04-14 14:08:47

标签: java c# c++ java-native-interface

我正在搞乱这项任务一段时间......

我试图从java调用C#DLL方法。

我使用this作为教程,它建议构建一个中间c ++ dll。但它使用的方法没有参数,我担心它需要修改使用带参数的方法。这是因为当我在java中调用t.SetCounter0(“aaa”)函数时,我得到了一个不满意的linkerror异常。

这是java代码:

package jniTester;

import java.io.Console;

public class Test1 {

static {
    //System.load("c:\\Users\\ttene\\Documents\\Visual Studio 2012\\Projects\\CPM\\CPMPerformanceCountersController\\x64\\Debug\\CppWrapperDll.dll");
    System.load("c:\\Users\\ttene\\Documents\\Cpm2Java\\CppWrapperDll.dll");
}

public native void SetCounter0(String x);

public static void main(String[] args) {

    try {
        Test1 t = new Test1();
        System.out.println("1");
        t.SetCounter0("aaa");
        System.out.println("2");

    } catch (Exception e) {
        e.printStackTrace();
    }
}

}

这是cpp:

#include <jni.h>
#include <iostream>

#include "Java\jnicall.h"
#include "MCPP\CppWrapperDll.h"

JNIEXPORT void JNICALL Java_Test1_SetCounter0  (JNIEnv *jn, jobject jobj) {

    std::cout << "Java_Test1_SetCounter0";

    // Instantiate the MC++ class.
    CppWrapperDllC* t = new CppWrapperDllC();

    // The actual call is made. 
    t->callCountersControl();
}

这是h文件:

#using <mscorlib.dll>
#using "CountersControl.netmodule"

using namespace System;

public __gc class CppWrapperDllC
{
    public:
        // Provide .NET interop and garbage collecting to the pointer.
        CountersControl __gc *t;

        CppWrapperDllC() {

            t = new CountersControl();
            // Assign the reference a new instance of the object
        }

    // This inline function is called from the C++ Code
    void callCountersControl() {

        t->SetCounter0("aaa");
    }
};

最后这是jni h文件:

#include <jni.h>
/* Header for class Test1 */

#ifndef _Included_Test1
#define _Included_Test1
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     Test1
 * Method:    SetCounter0
 * Signature: (Ljava/lang/String;)V
 */
JNIEXPORT void JNICALL Java_Test1_SetCounter0(JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

我会感激你的帮助。感谢。

1 个答案:

答案 0 :(得分:0)

您应该使用javah来创建JNI标头。如果您使用过它,标题中的声明实际上看起来像这样:

JNIEXPORT void JNICALL Java_Test1_SetCounter0(JNIEnv *, jobject, jstring);

其中jstring是作为参数传递给SetCounter0(...)的字符串。