【问题标题】:How to call a method in .Net DLL in a Java program如何在 Java 程序中调用 .Net DLL 中的方法
【发布时间】:2019-05-09 17:35:38
【问题描述】:

我尝试使用 Java 代码中的 .NET DLL,tsMemberFunctions.DLL 已成功加载,但代码无法调用实际函数。

参见下面的 sn-p:

public class tsMemberFunctions {  
    public native void GetMemberJSONSample();

    static {
        System.loadLibrary("tsMemberFunctions");
        System.out.println("Loaded");
    }

    public static void main(String[] args) {
        new tsMemberFunctions().GetMemberJSONSample();

    }
}

在执行上述方法时出现以下错误:

Loaded
Exception in thread "main" java.lang.UnsatisfiedLinkError: tsMemberFunctions.GetMemberJSONSample()V
    at tsMemberFunctions.GetMemberJSONSample(Native Method)
    at tsMemberFunctions.main(tsMemberFunctions.java:12)

如果我遗漏了代码中的任何内容或任何不正确的地方,有人可以告诉我,或者为这个用例建议更好的替代方案。 TIA。

【问题讨论】:

  • 为什么需要原生库来获取 JSON?我会弄清楚如何进行 HTTP 调用并以这种方式获取它。本机代码不是您可以选择的最便携的东西。
  • 你好,你可以忽略函数名,这个sn-p的主要目的是从dll文件中调用一个当前代码没有发生的方法。
  • 我的担忧仍然存在。你应该想别的办法。如果必须阅读,请阅读:docs.oracle.com/javase/8/docs/technotes/guides/jni

标签: java java-native-interface jni4net


【解决方案1】:

您必须非常小心名称和导出。

假设你有这个超级简单的库

// dllmain.cpp : Defines the entry point for the DLL application.
#include "pch.h"
#include "jni.h"
#include <stdio.h>

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

extern "C" JNIEXPORT void JNICALL Java_recipeNo001_HelloWorld_displayMessage

(JNIEnv* env, jclass obj) {

    printf("Hello world!\n");

}

您必须确保为正确的架构构建您的 DLL(这取决于您拥有的 Java 版本 - 32/64 位)。

假设你有x64 DLLx64 JDK,你可以这样调用你的lib

package recipeNo001;

public class HelloWorld {

    public static native void displayMessage();

    static {
        System.load("C:\\Users\\your_name\\Source\\Repos\\HelloWorld\\x64\\Debug\\HelloWorld.dll");
    }

    public static void main(String[] args) {
      HelloWorld.displayMessage();
    }
}

在您的情况下,我敢打赌您的代码中没有 extern "C" - 这就是 JVM 无法找到您的符号的原因。

在工具方面,我建议使用 Visual Studio 2019(在创建 DLL 时)和用于 Java 代码的 IntelliJ。

您可以在此处找到大量示例:http://jnicookbook.owsiak.org/ 和此处:https://github.com/mkowsiak/jnicookbook

【讨论】:

  • OP 使用了术语“.NET DLL”,这可能意味着他们正在使用依赖于 .NET 框架的托管 C++ 或 C# DLL。我不确定他们是否有extern "C" 接口。
  • 如果是这种情况(您有一个托管 DLL),则必须使用 C/C++ 本机桥接器。在桥内部,您必须加载 .Net DLL 并从 lib 运行代码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-18
  • 2016-12-24
  • 1970-01-01
  • 2023-03-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多