使用 JNI 将 C# 加载到 Java 项目时出现未解决的 link 错误
Unresolved link error using JNI to load C# into Java project
我正在尝试在我的 Java 项目中加载一个 DLL,以允许我使用 C# 中的一些代码。我做了一个示例并尝试在我的 Java 项目中实现它,但是当我尝试 运行 我的 Java 项目(设计器)时,我收到以下错误:
D:\RPMOpen\svnCobra\conversion\Designer>designer
D:\RPMOpen\svnCobra\conversion\Designer>java -jar Designer.jar "D:/RPMOpen/svnCobra"
Exception in thread "main" java.lang.UnsatisfiedLinkError: main/Designer.displayHeyLand()V
at main.Designer.main(Designer.java:491)
我感到好奇的是,我在 Java 项目中收到有关加载 DLL 的错误,我设法修复了该错误,并且在 Java 项目的以下代码中 如果我注释掉最后一行,我的 Designer 现在可以正常工作了。这向我表明我的 .DLL 实际上正在正确加载,但我真的很困惑为什么我会收到 UnsatisfiedLinkError。
Java项目示例代码:
static {
System.load("D://RPMOpen/svnCobra/Java/Designer/HeyLand.dll");
}
public native void displayHeyLand();
public static void main(String[] args)
{
if (args.length == 0)
{
throw new IllegalArgumentException("Conversion location required");
}
cobraLocation = args[0];
INPUT = cobraLocation + "/conversion/src/vb/";
OUTPUT = cobraLocation + "/conversion/aui/Designer/";
//System.loadLibrary(cobraLocation + "/conversion/Designer/GetFRXWrapper.dll");
//String s = getFromFRX();
//System.out.println(s);
Designer t = new Designer();
t.displayHeyLand();
试图实现的原始 C# 代码:
using System;
using System.Windows.Forms;
public class CSharpHeyLand
{
public CSharpHeyLand() { }
public void displayHeyLand()
{
MessageBox.Show("Hey Java, this is C#!", "Sample");
}
}
来自我的包装器的元素,包括一个 C++ 源文件和两个头文件:
//Cpp file HeyLand.cpp *******************************************
#include <jni.h>
#include "Java\HeyWork.h"
// managed c++ header containing call to c#
#include "MCPP\HeyLand.h"
// JNI call to managed C++ Class
JNIEXPORT void JNICALL Java_Main_Designer_displayHeyLand (JNIEnv *jn, jobject jobj) {
// istantiate the MC++ class.
HeyLandC* t = new HeyLandC();
// actual call is made.
t->callCSharpHeyLand();
}
//Header file HeyWork.h *******************************************
#include <jni.h>
/* Header for class Test1 */
#ifndef _Included_Designer
#define _Included_Designer
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: Designer
* Method: displayHeyLand
* Signature: (Ljava/lang/String;)V
*/
JNIEXPORT void JNICALL Java_Main_Designer_displayHeyLand
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
//Header file HeyLand.h *******************************************
#using <mscorlib.dll>
#using "/CSharpHeyLand.netmodule"
using namespace System;
public __gc class HeyLandC
{
public:
// provide .NET interop and garbage collecting to the pointer
CSharpHeyLand __gc *t;
HeyLandC() {
t = new CSharpHeyLand();
// Assign the reference a new instance of the object
}
// This inline function is called from the C++ Code
void callCSharpHeyLand() {
t->displayHeyLand();
}
};
非常感谢任何帮助!
几个月前我遇到了同样的错误。我们尝试使用来自 Java 的 C# DLL,这是我们所做的:
- 编写 C# DLL。
- 开发一个C++/CLI DLL作为C# DLL的包装器,导出需要的函数。
- 在Java中,加载C++/CLI DLL并通过JNI调用函数。
加载C++/CLI DLL已经OK,就像你的情况一样,在执行某些代码时,遇到UnsatisfiedLinkError错误,我们用Process Monitor跟踪它,这是因为java exe 未找到引用 C# 程序集。
与本机 C++ DLL 不同,引用的托管程序集不会在 exe 启动时立即加载,it is loaded as needed, this happens when the JIT compiler 在应用程序 运行 代码第一次到达时将 MSIL 代码转换为本机代码时间。这解释了当它到达该行代码时发生错误的时间。
所以要弄清楚这个问题,您可以使用进程监视器来监视 java.exe 以查看它是如何加载 DLL 的。据我观察,java exe 将尝试在以下位置找到 C# DLL:
- 在 global assembly cache.(GAC) 中排名第一。 GAC 中只有强名称程序集。
- java.exe的文件夹。
所以如果引用程序集不在这两个地方,你就会遇到那个错误。
您还可以创建一个 DEVPATH 环境变量来引用托管 DLL 的存储位置。在这种情况下,您必须设置 developmentMode on at machine.config file.
我正在尝试在我的 Java 项目中加载一个 DLL,以允许我使用 C# 中的一些代码。我做了一个示例并尝试在我的 Java 项目中实现它,但是当我尝试 运行 我的 Java 项目(设计器)时,我收到以下错误:
D:\RPMOpen\svnCobra\conversion\Designer>designer
D:\RPMOpen\svnCobra\conversion\Designer>java -jar Designer.jar "D:/RPMOpen/svnCobra"
Exception in thread "main" java.lang.UnsatisfiedLinkError: main/Designer.displayHeyLand()V
at main.Designer.main(Designer.java:491)
我感到好奇的是,我在 Java 项目中收到有关加载 DLL 的错误,我设法修复了该错误,并且在 Java 项目的以下代码中 如果我注释掉最后一行,我的 Designer 现在可以正常工作了。这向我表明我的 .DLL 实际上正在正确加载,但我真的很困惑为什么我会收到 UnsatisfiedLinkError。
Java项目示例代码:
static {
System.load("D://RPMOpen/svnCobra/Java/Designer/HeyLand.dll");
}
public native void displayHeyLand();
public static void main(String[] args)
{
if (args.length == 0)
{
throw new IllegalArgumentException("Conversion location required");
}
cobraLocation = args[0];
INPUT = cobraLocation + "/conversion/src/vb/";
OUTPUT = cobraLocation + "/conversion/aui/Designer/";
//System.loadLibrary(cobraLocation + "/conversion/Designer/GetFRXWrapper.dll");
//String s = getFromFRX();
//System.out.println(s);
Designer t = new Designer();
t.displayHeyLand();
试图实现的原始 C# 代码:
using System;
using System.Windows.Forms;
public class CSharpHeyLand
{
public CSharpHeyLand() { }
public void displayHeyLand()
{
MessageBox.Show("Hey Java, this is C#!", "Sample");
}
}
来自我的包装器的元素,包括一个 C++ 源文件和两个头文件:
//Cpp file HeyLand.cpp *******************************************
#include <jni.h>
#include "Java\HeyWork.h"
// managed c++ header containing call to c#
#include "MCPP\HeyLand.h"
// JNI call to managed C++ Class
JNIEXPORT void JNICALL Java_Main_Designer_displayHeyLand (JNIEnv *jn, jobject jobj) {
// istantiate the MC++ class.
HeyLandC* t = new HeyLandC();
// actual call is made.
t->callCSharpHeyLand();
}
//Header file HeyWork.h *******************************************
#include <jni.h>
/* Header for class Test1 */
#ifndef _Included_Designer
#define _Included_Designer
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: Designer
* Method: displayHeyLand
* Signature: (Ljava/lang/String;)V
*/
JNIEXPORT void JNICALL Java_Main_Designer_displayHeyLand
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
//Header file HeyLand.h *******************************************
#using <mscorlib.dll>
#using "/CSharpHeyLand.netmodule"
using namespace System;
public __gc class HeyLandC
{
public:
// provide .NET interop and garbage collecting to the pointer
CSharpHeyLand __gc *t;
HeyLandC() {
t = new CSharpHeyLand();
// Assign the reference a new instance of the object
}
// This inline function is called from the C++ Code
void callCSharpHeyLand() {
t->displayHeyLand();
}
};
非常感谢任何帮助!
几个月前我遇到了同样的错误。我们尝试使用来自 Java 的 C# DLL,这是我们所做的:
- 编写 C# DLL。
- 开发一个C++/CLI DLL作为C# DLL的包装器,导出需要的函数。
- 在Java中,加载C++/CLI DLL并通过JNI调用函数。
加载C++/CLI DLL已经OK,就像你的情况一样,在执行某些代码时,遇到UnsatisfiedLinkError错误,我们用Process Monitor跟踪它,这是因为java exe 未找到引用 C# 程序集。
与本机 C++ DLL 不同,引用的托管程序集不会在 exe 启动时立即加载,it is loaded as needed, this happens when the JIT compiler 在应用程序 运行 代码第一次到达时将 MSIL 代码转换为本机代码时间。这解释了当它到达该行代码时发生错误的时间。
所以要弄清楚这个问题,您可以使用进程监视器来监视 java.exe 以查看它是如何加载 DLL 的。据我观察,java exe 将尝试在以下位置找到 C# DLL:
- 在 global assembly cache.(GAC) 中排名第一。 GAC 中只有强名称程序集。
- java.exe的文件夹。
所以如果引用程序集不在这两个地方,你就会遇到那个错误。
您还可以创建一个 DEVPATH 环境变量来引用托管 DLL 的存储位置。在这种情况下,您必须设置 developmentMode on at machine.config file.