C#和Java互相调用的方法小结

 更新时间:2025年04月02日 09:34:42   作者:老胖闲聊  
这篇文章主要介绍了C#和Java互相调用的方法,文中展示了如何在不同编程语言之间实现互操作,每种语言之间的互操作都有其特定的方法和工具,希望这些示例能够帮助你更好地理解和实现跨语言调用,需要的朋友可以参考下

C# 调用 Java 类和方法(IKVM / JNI-JNA 桥接)

一、前置条件

  1. 环境要求
    • IKVM:安装 IKVM 工具包(包含 ikvmcikvm 等工具),需要 JDK 和 .NET Framework。
    • JNI/JNA:需要 Java JDK(包含 javacjavah)和 .NET 的 P/Invoke 支持。
  2. 文件准备
    • Java JAR 包(如 example.jar)。
    • Java 类的完整定义(需公开目标类和方法)。

二、方法 1:使用 IKVM 桥接

原理:将 Java 字节码转换为 .NET 程序集(DLL),直接在 C# 中引用。

实现步骤:

  • 安装 IKVM
  • 转换 JAR 到 .NET DLL
ikvmc -target:library example.jar -out:Example.dll
  • 在 C# 中引用 DLL
using IKVM.Runtime;
using java.example; // 对应 Java 包名

public class Program {
    public static void Main() {
        // 调用 Java 类
        ExampleClass obj = new ExampleClass();
        obj.exampleMethod("Hello from C#");
    }
}

注意事项:

  • 确保 Java 类和方法是 public 的。
  • 转换过程中可能丢失部分 Java 特性(如动态代理)。

三、方法 2:使用 JNI/JNA 桥接

原理:通过 JNI 调用 Java 虚拟机(JVM),C# 通过 P/Invoke 调用 JNI 接口。

实现步骤:

  • 编写 Java 本地接口(JNI)
public class NativeBridge {
    public static native void callFromCSharp(String message);
}
  • 生成 C/C++ 头文件
javac NativeBridge.java
javah -jni NativeBridge
  • 生成 NativeBridge.h
  • 实现 C/C++ 桥接层
#include <jni.h>
#include "NativeBridge.h"

JNIEXPORT void JNICALL Java_NativeBridge_callFromCSharp(JNIEnv *env, jclass cls, jstring msg) {
    const char *cMsg = env->GetStringUTFChars(msg, 0);
    printf("Java received: %s\n", cMsg);
    env->ReleaseStringUTFChars(msg, cMsg);
}
  • 编译为 DLL
gcc -shared -I"%JAVA_HOME%\include" -I"%JAVA_HOME%\include\win32" NativeBridge.c -o NativeBridge.dll
  • C# 调用 DLL
using System;
using System.Runtime.InteropServices;

public class Program {
    [DllImport("NativeBridge.dll")]
    private static extern void Java_NativeBridge_callFromCSharp(string message);

    public static void Main() {
        Java_NativeBridge_callFromCSharp("Hello via JNI");
    }
}

注意事项:

  • 需要手动管理 JVM 生命周期(JNI_CreateJavaVM)。
  • 跨平台需重新编译 DLL/SO。

四、常见问题

  1. IKVM 转换失败
    • 缺少依赖 JAR 包时,需添加 -reference:other.jar
  2. JNI 内存泄漏
    • 使用 ReleaseStringUTFChars 释放资源。
  3. DLL 路径问题
    • 确保 DLL 在输出目录或 PATH 环境变量中。

五、高级特性

  1. IKVM 动态类加载
var classLoader = new ikvm.runtime.AssemblyClassLoader(typeof(Program).Assembly);
var clazz = classLoader.loadClass("java.example.DynamicClass");
  • JNI 回调 C# 方法
    • 在 C/C++ 层定义回调函数,通过 P/Invoke 调用 C# 委托。

Java 调用 DLL 的类和方法(JNA)

一、前置条件

  1. 环境要求
  2. 文件准备
    • 目标 DLL(如 NativeLib.dll)及其函数签名。

二、使用 JNA 方法

原理:通过 JNA 库直接映射 DLL 函数到 Java 接口,无需编写 C 代码。

实现步骤:

  1. 添加 JNA 依赖
<!-- Maven -->
<dependency>
    <groupId>net.java.dev.jna</groupId>
    <artifactId>jna</artifactId>
    <version>5.13.0</version>
</dependency>
  • 定义 Java 接口
import com.sun.jna.Library;
import com.sun.jna.Native;

public interface NativeLib extends Library {
    NativeLib INSTANCE = Native.load("NativeLib", NativeLib.class);
    
    // 映射 DLL 函数
    void exampleFunction(String message);
    int addNumbers(int a, int b);
}
  • 调用 DLL 函数
public class Main {
    public static void main(String[] args) {
        NativeLib.INSTANCE.exampleFunction("Hello from Java");
        int sum = NativeLib.INSTANCE.addNumbers(3, 4);
        System.out.println("Sum: " + sum);
    }
}

注意事项:

  • 函数名和参数类型需与 DLL 严格匹配。
  • 支持复杂类型(结构体、指针)需使用 Structure 类。

三、高级特性

回调函数

public interface CallbackLib extends Library {
    interface Callback extends CallbackProxy {
        void invoke(String result);
    }
    void registerCallback(Callback callback);
}

结构体映射

public class Point extends Structure {
    public int x;
    public int y;
}

四、常见问题

  1. UnsatisfiedLinkError
    • 检查 DLL 名称和路径,确保 32/64 位一致。
  2. 参数类型不匹配
    • 使用 Native.getNativeSize() 调试类型大小。

总结

  • C# 调用 Java:优先使用 IKVM 简单场景,JNI 用于高性能需求。
  • Java 调用 DLL:JNA 是最简方案,无需编写 C 代码。
  • 代码可维护性:跨语言调用需详细文档记录接口约定。

以上就是C#和Java互相调用的方法小结的详细内容,更多关于C#和Java互相调用的资料请关注脚本之家其它相关文章!

相关文章

  • C#识别出图片里的数字和字母

    C#识别出图片里的数字和字母

    本文给大家分享的是C#识别出图片里的数字和字母的代码,主要是识别以前公司的软件注册码截图里的数字和字母,功能很简单,也存在很大的局限性,这里仅仅是分享,小伙伴们参考下。
    2015-03-03
  • C#服务器NFS共享文件夹搭建与上传图片文件的实现

    C#服务器NFS共享文件夹搭建与上传图片文件的实现

    本文主要介绍了C#服务器NFS共享文件夹搭建与上传图片文件的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-07-07
  • C# 并行和多线程编程——Task进阶知识

    C# 并行和多线程编程——Task进阶知识

    这篇文章主要介绍了C# 并行和多线程编程——Task进阶知识的的相关资料,帮助大家更好的理解和学习使用c#,感兴趣的朋友可以了解下
    2021-02-02
  • C#排序算法之快速排序

    C#排序算法之快速排序

    下面给出的代码是以数组最后一个元素作为参考元素,这仅是参考元素选取的方式之一。
    2010-09-09
  • C#实现无损压缩图片代码示例

    C#实现无损压缩图片代码示例

    这篇文章介绍了C#实现无损压缩图片的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-04-04
  • 使用 CliWrap 让C#中的命令行交互(推荐)

    使用 CliWrap 让C#中的命令行交互(推荐)

    这篇文章主要介绍了使用 CliWrap 让C#中的命令行交互举重若轻,这是一个在 .NET 平台使用的命令行交互工具库, 通过在C# 中使用 Fluent 的API, 让命令行交互,感兴趣的朋友跟随小编一起看看吧
    2021-12-12
  • C# DateTime日期比较方法案例详解

    C# DateTime日期比较方法案例详解

    这篇文章主要介绍了C# DateTime日期比较方法案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-08-08
  • Unity相机移动之屏幕边缘检测

    Unity相机移动之屏幕边缘检测

    这篇文章主要为大家详细介绍了Unity相机移动之屏幕边缘检测,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-02-02
  • 基于C#实现乱码视频效果

    基于C#实现乱码视频效果

    乱码视频效果可能很多人都在抖音看到过,即把一个短视频,转成数字、字母等乱码组成的形式进行播放。本文将用C#实现一下这一效果,感兴趣的可以了解一下
    2023-01-01
  • C#实现读写CSV文件的方法详解

    C#实现读写CSV文件的方法详解

    项目中经常遇到CSV文件的读写需求,其中的难点主要是CSV文件的解析。本文会介绍CsvHelper、TextFieldParser、正则表达式三种解析CSV文件的方法,需要的可以参考一下
    2022-06-06

最新评论