从 Java 应用程序调用 C# 库:进程因 StackOverflowException 而终止
Calling C# library from Java application: Process is terminated due to StackOverflowException
我有一个简单的 C# class 库,我将它包装在 C++/CLI class 库中并将其加载到一个简单的 Java 控制台应用程序中。但是当我 运行 Java 应用程序时,出现以下错误:
Process is terminated due to WhosebugException.
Process finished with exit code -1073741571 (0xC00000FD)
我的 C# 库有一个 Class1.cs 文件:
using System;
namespace CSharpClassLibrary1
{
public class Class1
{
public Class1() { }
public void Print()
{
Console.WriteLine("Hello World From C#!");
}
}
}
我的 C++/CLI 包装器有两个文件:HelloWorld.h 和 CppClassLibrary1.cpp。
HelloWorld.h:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class HelloWorld */
#ifndef _Included_HelloWorld
#define _Included_HelloWorld
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: HelloWorld
* Method: print
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_HelloWorld_print
(JNIEnv*, jobject);
#ifdef __cplusplus
}
#endif
#endif
我通过 运行 在我的 Java 应用程序中使用以下形式的命令得到它:javac -h <directory> -d <directory> <source files>
.
CppClassLibrary1.cpp:
#include "pch.h"
#include "HelloWorld.h"
using namespace CSharpClassLibrary1;
JNIEXPORT void JNICALL Java_HelloWorld_print(JNIEnv* env, jobject obj)
{
Class1^ cls = gcnew Class1();
cls->Print();
}
我添加了 CSharpClassLibrary1 作为对 C++/CLI 包装器的引用。
我在 "Include directories" 设置中添加了以下路径:
C:\Users\ns16\AppData\Local\JetBrains\Toolbox\apps\IDEA-C\ch-02.6817.14\jbr\include
C:\Users\ns16\AppData\Local\JetBrains\Toolbox\apps\IDEA-C\ch-02.6817.14\jbr\include\win32
我的 Java 应用程序有一个 HelloWorld.java 文件:
public class HelloWorld {
public native void print();
static {
try {
System.loadLibrary("CppClassLibrary1");
} catch (UnsatisfiedLinkError e) {
System.err.println("Native code library failed to load.\n" + e);
}
}
public static void main(String[] args) {
HelloWorld hw = new HelloWorld();
hw.print();
}
}
我在 java.library.path 变量中指定了 CppClassLibrary1 库路径。
请帮帮我!我做错了什么?
更新。对该问题的研究显示如下:
在Java应用程序错误出现在hw.print();
行。注释掉,应用启动成功。
如果在 CppClassLibrary1.cpp 文件的 C++/CLI 包装器中将 Java_HelloWorld_print
函数体替换为 std::cout << "Hello World From C++/CLI!";
行,Java 应用程序将成功启动并打印 Hello World From C++/CLI!
字符串。
如果您创建 C# 控制台应用程序,将 C# 库作为引用添加到其中,并将 Class1 cls = new Class1(); cls.print();
代码添加到 Main
方法中,应用程序将成功启动并打印Hello World From C#!
字符串.
我用 java.exe 文件复制了目录中的 C# 库程序集(在我的系统中它位于 C:\Users\ns16\AppData\Local\JetBrains\Toolbox\apps\IDEA-C\ch-02.6817.14\jbr\bin
),现在 Java 应用程序可以运行了!我不想将程序集移出项目目录,但这是我找到的唯一解决方案。
我有一个简单的 C# class 库,我将它包装在 C++/CLI class 库中并将其加载到一个简单的 Java 控制台应用程序中。但是当我 运行 Java 应用程序时,出现以下错误:
Process is terminated due to WhosebugException.
Process finished with exit code -1073741571 (0xC00000FD)
我的 C# 库有一个 Class1.cs 文件:
using System;
namespace CSharpClassLibrary1
{
public class Class1
{
public Class1() { }
public void Print()
{
Console.WriteLine("Hello World From C#!");
}
}
}
我的 C++/CLI 包装器有两个文件:HelloWorld.h 和 CppClassLibrary1.cpp。
HelloWorld.h:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class HelloWorld */
#ifndef _Included_HelloWorld
#define _Included_HelloWorld
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: HelloWorld
* Method: print
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_HelloWorld_print
(JNIEnv*, jobject);
#ifdef __cplusplus
}
#endif
#endif
我通过 运行 在我的 Java 应用程序中使用以下形式的命令得到它:javac -h <directory> -d <directory> <source files>
.
CppClassLibrary1.cpp:
#include "pch.h"
#include "HelloWorld.h"
using namespace CSharpClassLibrary1;
JNIEXPORT void JNICALL Java_HelloWorld_print(JNIEnv* env, jobject obj)
{
Class1^ cls = gcnew Class1();
cls->Print();
}
我添加了 CSharpClassLibrary1 作为对 C++/CLI 包装器的引用。
我在 "Include directories" 设置中添加了以下路径:
C:\Users\ns16\AppData\Local\JetBrains\Toolbox\apps\IDEA-C\ch-02.6817.14\jbr\include
C:\Users\ns16\AppData\Local\JetBrains\Toolbox\apps\IDEA-C\ch-02.6817.14\jbr\include\win32
我的 Java 应用程序有一个 HelloWorld.java 文件:
public class HelloWorld {
public native void print();
static {
try {
System.loadLibrary("CppClassLibrary1");
} catch (UnsatisfiedLinkError e) {
System.err.println("Native code library failed to load.\n" + e);
}
}
public static void main(String[] args) {
HelloWorld hw = new HelloWorld();
hw.print();
}
}
我在 java.library.path 变量中指定了 CppClassLibrary1 库路径。
请帮帮我!我做错了什么?
更新。对该问题的研究显示如下:
在Java应用程序错误出现在
hw.print();
行。注释掉,应用启动成功。如果在 CppClassLibrary1.cpp 文件的 C++/CLI 包装器中将
Java_HelloWorld_print
函数体替换为std::cout << "Hello World From C++/CLI!";
行,Java 应用程序将成功启动并打印Hello World From C++/CLI!
字符串。如果您创建 C# 控制台应用程序,将 C# 库作为引用添加到其中,并将
Class1 cls = new Class1(); cls.print();
代码添加到Main
方法中,应用程序将成功启动并打印Hello World From C#!
字符串.
我用 java.exe 文件复制了目录中的 C# 库程序集(在我的系统中它位于 C:\Users\ns16\AppData\Local\JetBrains\Toolbox\apps\IDEA-C\ch-02.6817.14\jbr\bin
),现在 Java 应用程序可以运行了!我不想将程序集移出项目目录,但这是我找到的唯一解决方案。