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

How to call a function with arguments in C++ from JAVA using JNI?

我在这个任务上纠结了一段时间...

我正在尝试从 java 调用 C# DLL 方法。

我使用 this 作为教程,它建议构建一个中级 c++ dll。但是它使用了一个不带参数的方法,我担心它需要修改才能使用带参数的方法。这是因为当我在 java.

中调用 t.SetCounter0("aaa") 函数时,我得到了一个 unsatisfiedlinkerror 异常

这是 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

非常感谢你的帮助。谢谢。

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

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

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