是否可以制作一个调用 jdbc 的 Java JNI?

2023-11-29

我是 jni 的新手,并且非常困惑是否可以使用 jni 来实现我需要完成的任务。我想制作一个java api,它将使用jdbc来更新数据库,但是这个特定的api将从C++程序中调用。

所以我想我可能应该编写通过 jdbc 访问数据库的 jni 代码(这可能吗?),创建 C++ 代码并生成 dll,以便其他 C++ 程序可以调用 dll 来更新数据库。这一切可能吗?如果是这样,我如何真正在jni中调用jdbc? 如果这个dll最终做出来,Fortran也能调用它吗?

我的另一个想法是也许我应该制作一个常规的java程序来更新数据库,然后使用ikvm将java类包装到C++ dll中?

问题是我必须使用 Java 来使用 Access 数据库。我们的C++程序根本不会访问数据库,如果这个java api可以通过系统调用来访问就更好了。

或者有什么更好的方法可以做到吗?

我希望我解释得很好。我不太熟悉我在这里分配的内容,也找不到太多相关参考资料。

太感谢了!!

UPDATED:问题是并非所有计算机都安装了 C++ postgresql 驱动程序,但它们确实安装了 Java postgresql 驱动程序。我们不想强迫每个人都安装 C++ 数据库驱动程序,并且不会对这些 C++ 程序进行重大更改。因此,用 Java 来访问数据库是有意义的。基本上调用java系统服务(首选,例如dll?)/API来记录C++程序的开始时间和结束时间。 C++ 程序将生成一个“函数”调用(带传入参数和返回值)到此系统服务/Java API 来记录开始/结束时间。


我不会告诉你正确或错误的方法来完成你想做的事情。但是,如果您尝试调用 Java 代码 (JDBC.jar),那么以下内容适合您。否则请随意投反对票。

JVM.hpp:

#ifndef JVM_HPP_INCLUDED
#define JVM_HPP_INCLUDED

#include "../java/jni.h"
#include <windows.h>
#include <iostream>
#include <stdexcept>
#include <algorithm>

class Jvm
{
    private:
        JavaVM* jvm;
        JNIEnv* env;
        JavaVMInitArgs jvm_args;
        jclass systemClassLoader;

    public:
        Jvm(std::string ClassPath = ".");
        ~Jvm();

        inline JavaVM* GetJVM() const {return jvm;}
        inline JNIEnv* GetENV() const {return env;}
        inline jclass GetSystemClassLoader() const {return systemClassLoader;}
        void DestroyJVM();
        void PrintStackTrace();
        jclass DefineClass(const char* FullClassName, const void* ClassBuffer, std::uint32_t BufferLength);
        jclass DefineClass(const char* FullClassName, jobject ClassLoader, const void* ClassBuffer, std::uint32_t BufferLength);

        void RegisterNativeMethod(const char* MethodName, const char* MethodSignature, void* func_ptr);
        void RegisterNativeMethod(jobject ClassLoader, const char* MethodName, const char* MethodSignature, void* func_ptr);
        void RegisterNativeMethods(JNINativeMethod* Methods, std::uint32_t MethodCount);
        void RegisterNativeMethods(jobject ClassLoader, JNINativeMethod* Methods, std::uint32_t MethodCount);

    protected:
        void InitClassLoader();
};

#endif // JVM_HPP_INCLUDED

JVM.cpp:

#include "JVM.hpp"

Jvm::~Jvm()
{
    env->DeleteGlobalRef(this->systemClassLoader);
    jvm->DestroyJavaVM();
}

Jvm::Jvm(std::string ClassPath) : jvm(NULL), env(NULL), jvm_args(), systemClassLoader(NULL)
{
    JavaVMOption* options = new JavaVMOption[2];
    jvm_args.version = JNI_VERSION_1_6;
    JNI_GetDefaultJavaVMInitArgs(&jvm_args);
    options[0].optionString = const_cast<char*>("-Djava.compiler=NONE");
    options[1].optionString = const_cast<char*>(("-Djava.class.path=" + ClassPath).c_str());
    jvm_args.nOptions = 2;
    jvm_args.options = options;
    jvm_args.ignoreUnrecognized = false;

    if (JNI_CreateJavaVM(&jvm, reinterpret_cast<void**>(&env), &jvm_args))
    {
        delete[] options;
        throw std::runtime_error("Failed To Create JVM Instance.");
    }

    delete[] options;
}

void Jvm::InitClassLoader()
{
    if (!this->systemClassLoader)
    {
        jclass classloader = env->FindClass("Ljava/lang/ClassLoader;");
        if (!classloader)
        {
            throw std::runtime_error("Failed To find ClassLoader.");
        }

        jmethodID SystemLoaderMethod = env->GetStaticMethodID(classloader, "getSystemClassLoader", "()Ljava/lang/ClassLoader;");
        jobject loader = env->CallStaticObjectMethod(classloader, SystemLoaderMethod);
        this->systemClassLoader = reinterpret_cast<jclass>(env->NewGlobalRef(loader));
    }
}

void Jvm::PrintStackTrace()
{
    if (env->ExceptionOccurred())
    {
        env->ExceptionDescribe();
        env->ExceptionClear();
    }
}

jclass Jvm::DefineClass(const char* FullClassName, const void* ClassBuffer, std::uint32_t BufferLength)
{
    this->InitClassLoader();
    return this->DefineClass(FullClassName, this->systemClassLoader, ClassBuffer, BufferLength);
}

jclass Jvm::DefineClass(const char* FullClassName, jobject ClassLoader, const void* ClassBuffer, std::uint32_t BufferLength)
{
    return ClassLoader ? env->DefineClass(FullClassName, ClassLoader, static_cast<const jbyte*>(ClassBuffer), BufferLength) : NULL;
}

void Jvm::RegisterNativeMethod(const char* MethodName, const char* MethodSignature, void* func_ptr)
{
    JNINativeMethod method;
    method.name = const_cast<char*>(MethodName);
    method.signature = const_cast<char*>(MethodSignature);
    method.fnPtr = func_ptr;
    this->RegisterNativeMethods(&method, 1);
}

void Jvm::RegisterNativeMethod(jobject ClassLoader, const char* MethodName, const char* MethodSignature, void* func_ptr)
{
    JNINativeMethod method;
    method.name = const_cast<char*>(MethodName);
    method.signature = const_cast<char*>(MethodSignature);
    method.fnPtr = func_ptr;
    this->RegisterNativeMethods(ClassLoader, &method, 1);
}

void Jvm::RegisterNativeMethods(JNINativeMethod* Methods, std::uint32_t MethodCount)
{
    this->InitClassLoader();
    this->RegisterNativeMethods(this->systemClassLoader, Methods, MethodCount);
}

void Jvm::RegisterNativeMethods(jobject ClassLoader, JNINativeMethod* Methods, std::uint32_t MethodCount)
{
    if (ClassLoader)
    {
        env->RegisterNatives(static_cast<jclass>(ClassLoader), Methods, MethodCount);
    }
}

然后您可以创建一个加载您的 jar 的实例。

int main()
{
    Jvm VM("C:/Users/Brandon/IdeaProjects/Eos/out/production/Eos/Bot.jar");

    jclass jMain = VM.GetENV()->FindClass("eos/Main");

    if (jMain != nullptr)
    {
        jmethodID mainMethod = env->GetStaticMethodID(jMain, "main", "([Ljava/lang/String;)V");
        jclass StringClass = env->FindClass("java/lang/String");
        jobjectArray Args = env->NewObjectArray(0, StringClass, 0);
        env->CallStaticVoidMethod(jMain, MainMethod, Args);
    }
}

现在这只是展示如何使用 Main 方法运行 jar。但是,您可以从 jar 中访问任何类,并使用所需的多个参数来调用它。它不需要主线。

现在要做到这一点还有很多工作要做,但我不会教训你。问题是这是否可能,答案是肯定的.. 是的。只要你创建一个“JVM”的实例。之后,就需要通过“Package/Class”而不是“Package.Class”(如 Java 中那样)访问该类。然后调用您想要的任何方法。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

是否可以制作一个调用 jdbc 的 Java JNI? 的相关文章

  • Monotouch全局异常处理

    我在野外发现了一只令人讨厌的虫子 但我无法确定它的具体情况 有没有办法拥有全局 Try Catch 块 或者有办法处理 Monotouch 中未处理的任何异常 我可以包起来吗UIApplication Main args 在 try cat
  • Linq 合并列表

    我的课 public class Foo public int A get set public List
  • 多对多不检索映射数据

    Spring boot 2 5 6 我无法安装版本 概要文件 java Getter Setter NoArgsConstructor AllArgsConstructor EqualsAndHashCode FieldDefaults l
  • C# 枚举到字符串自动转换?

    是否可以让编译器自动将我的 Enum 值转换为字符串 这样我就可以避免每次都显式调用 ToString 方法 这是我想做的一个例子 enum Rank A B C Rank myRank Rank A string myString Ran
  • 如何将STL容器数据转储到gdb中?

    我无法在 gdb 中转储 STL 无序映射容器值 变量类型是 std unordered map var 我的 gdb 版本 7 7 1 GDB配置 configure host x86 64 linux gnu target x86 64
  • 处理照片上传的最佳方式是什么?

    我正在为一个家庭成员的婚礼制作一个网站 他们要求的一个功能是一个照片部分 所有客人都可以在婚礼结束后前往并上传他们的照片 我说这是一个很棒的想法 然后我就去实现它 那么只有一个问题 物流 上传速度很慢 现代相机拍摄的照片很大 2 5 兆 我
  • 如何从外语线程调用Python函数(C++)

    我正在开发一个程序 使用 DirectShow 来抓取音频数据 媒体文件 DirectShow 使用线程将音频数据传递给回调 我的程序中的函数 然后我让该回调函数调用另一个函数 Python 中的函数 我使用 Boost Python 来包
  • 如何告诉 IntelliJ 使用 Java 1.6 JDK 启动 gradle?

    一个简单的问题 即使经过几个小时的尝试和搜索 我也无法弄清楚 我安装了 Java 6 和 7 如何告诉 IntelliJ 使用 JDK 版本 1 6 启动 Gradle 构建 无论我做什么 IntelliJ 都会以以下方式开始我的 grad
  • Microsoft JDBC 中的 JTDS 属性相当于什么?

    我正在将 JTDS 连接更改为 Microsoft JDBC 并且我看到存在于http jtds sourceforge net faq html http jtds sourceforge net faq htmlMicrosoft JD
  • Checkstyle - 方法按修饰符排序

    是否可以添加到 checkstyle 规则以按修饰符对类中的方法进行排序 我的意思是开头的公共方法和最后的私有方法 MethodsOrderCheck做这个工作 检查文档 https www qulice com qulice checks
  • 使用数据绑定,如何将包含表情符号的文本绑定到标签并使其正确显示?

    我正在编写一个应用程序来连接 WordPress BuddyPress API 该应用程序将允许用户通过 API 相互发送消息 当这些消息包含表情符号时 我很难正确显示它们 以下是 API 返回的消息文本的简短示例 Hi x1f642 ho
  • spring data jpa 过滤 @OneToMany 中的子项

    我有一个员工测试实体是父实体并且FunGroup信息子实体 这两个实体都是通过employeeId映射 我需要一种方法来过滤掉与搜索条件匹配的子实体 以便结果仅包含父实体和子实体 满足要求 员工测试类 Entity name Employe
  • JSP 和 scriptlet

    我知道现在使用 scriptlet 被认为是禁忌 没关系 我会同意Top Star的话 因为我目前只是Java新手 到目前为止我听到的是 它是为了让设计师的生活更轻松 但我想知道 这是否与JSP页面的性能有关 另一方面 如果只是为了 让设计
  • 如何检测应用程序正在运行的 .NET 版本?

    我尝试使用Environment Version ToString 确定目标计算机上正在使用什么 NET 框架 但安装了 4 0 版本时 它说我正在使用 NET 2 0 如何检测目标计算机上正在运行的 NET Framework 版本 En
  • 如何将System.Windows dll添加到Visual Studio 2010 Express?

    我正在开发一个小型应用程序C and VS2010 as IDE with NET框架4 我想用CaptureSource类以便从笔记本电脑的网络摄像头捕获视频 为此我需要添加一个命名空间System Windows DependencyO
  • 如何从 Access 数据库中读取“是/否”值作为布尔值?

    帮我找回YES NO来自 MS Access 的布尔格式数据类型 我尝试解析它 但它总是返回 false 更新 实际上不是问题抱歉 它确实接受 YES NO 作为布尔值 OleDbconnection dbConnect new OleDb
  • 将带有时区的 Joda-Time `DateTime` 转换为没有时区的 DateTime?

    Given a DateTime http www joda org joda time apidocs org joda time DateTime html例如2015 07 09T05 10 00 02 00 using 乔达时间 h
  • 当我的进程被终止时到底会发生什么?

    我有一个包含本机代码和托管代码的混合进程 在 Windows Server 2003 上运行 当我从进程资源管理器中终止进程时 它会进入 100 cpu 的状态 并在消失之前保持这种状态一段时间 有时甚至 10 分钟 在此期间我无法 杀死
  • 实体框架代码首次日期字段创建

    我正在使用实体框架代码优先方法来创建我的数据库表 下面的代码 创建一个DATETIME数据库中的列 但我想创建一个DATE柱子 DataType DataType Date DisplayFormatAttribute ApplyForma
  • 将一个 IEnumerable 拆分为多个 IEnumerable

    我是 linq 新手 我需要根据指示器将 Couple string text bool Indicator 类型的 IEnumerable 拆分为多个 IEnumerable 我尝试使用skipWhile 和 TakeWhile 但没有找

随机推荐

  • 使用请求登录有问题的站点

    我正在尝试使用 requests 模块在 python 中创建一个脚本来登录到此site 我正在使用我的凭据 但我找不到任何方法来这样做 因为我看不到与请求一起发送所需的参数 在 Chrome 开发工具中 username SIMMTH i
  • 如何使用Maven PDF插件从Surefire Report生成PDF?

    运行 JUnit 测试后 我使用 Maven Surefire Report 插件 http maven apache org plugins maven surefire report plugin 生成 HTML 测试报告 这会产生以下
  • Kubernetes 中的 TCP 入口支持

    似乎 TCP 和 UDP 支持将在下一版本的 ingress nginx 控制器中被弃用 还有其他入口控制器支持 TCP 和 UDP 吗 或任何其他在 kubernetes 之外公开非 http 端口的解决方案 kubernetes 初学者
  • 如何在 Excel 工作表中查找精确值

    如何在 Excel 工作表中找到字符串值 我在尝试objRange Find 但这也给了我错误的地址 例如 我想要 Object paint 的地址 但它也给出 Object paint and stk 的地址 我应该如何获得精确的值 Se
  • Spring boot war文件部署在Tomcat上

    我使用 Spring Boot 1 2 4 RELEASEGS 休息服务源文件 我有 127 0 0 1 18 Jun 2015 09 59 25 0300 GET gs rest service 0 1 0 HTTP 1 1 404 10
  • Mac OS X:_tkinter.TclError:没有显示名称,也没有 $DISPLAY 环境变量

    正如我所说 我已经从 Macports 安装了 Python 3 3 现在 当我重点搜索 空闲 时 Idle Python 3 3 出现 但是 当我尝试单击它时 什么也没有发生 没有显示任何错误或任何东西 它显然不会启动 您认为可能有什么问
  • 为什么要在数据库中创建视图?

    何时以及为何有人决定需要在数据库中创建视图 为什么不直接运行一个普通的存储过程或选择呢 视图提供了多种好处 1 视图可以隐藏复杂性 如果您的查询需要连接多个表 或者具有复杂的逻辑或计算 则可以将所有逻辑编码到视图中 然后像选择表一样从视图中
  • 移动当前可执行文件c#

    我想将当前正在执行的程序集移动到 C 驱动器 当我尝试以下代码时 File Move Assembly GetEntryAssembly Location c 它给了我一个错误 mscorlib dll 中发生 System Unautho
  • Java线程安全数据库连接

    我正在编写一个 servlet 它通过访问和修改数据库中的某些表来处理每个请求 我希望与数据库的连接是线程安全的 我不想为此使用现有的库 框架 spring hibernate 等 我知道我可以通过以下方式使用 java 的 ThreadL
  • 与 multiprocessing.Pool 共享计数器

    我想用multiprocessing Value multiprocessing Lock在不同的进程之间共享一个计数器 例如 import itertools as it import multiprocessing def func x
  • .NET MAUI绑定ListView的ItemSelected事件到ViewModel

    我正在尝试将 ListView 的 ItemSelected 绑定到视图模型 但遇到了一些问题 由于我自己对其工作原理的误解 我有观点
  • Python 和 Ctypes:将结构体作为指针传递给函数以获取数据

    我已经查看了其他答案 但似乎无法使其发挥作用 我正在尝试调用 DLL 中的函数来与 SMBus 设备进行通信 该函数接受一个指向结构的指针 该结构有一个数组作为其字段之一 所以 In C typedef struct SMB REQUEST
  • 托管 Bean 内的回滚事务

    我想不在 EJB 内回滚事务 而是在 JSF 托管 bean 内回滚事务 在EJB内部我们可以使用SessionContext setRollBackOnly 但我可以在托管 bean 中使用什么 Stateless Local Accou
  • List和ArrayList这句话是什么意思?

    我正在阅读 Drools Planner 示例 并且经常遇到这样的代码 List
  • 包含彼此了解的字段的结构

    我有一组需要相互了解才能合作的对象 这些对象存储在容器中 我试图对如何用 Rust 构建我的代码有一个非常简单的想法 让我们打个比方 AComputer包含 1 Mmu 1 Ram 1 Processor In Rust struct Co
  • 使用hadoop流解压文件

    我在 HDFS 中有很多文件 所有这些文件都是一个 zip 文件 其中包含一个 CSV 文件 我正在尝试解压缩这些文件 以便可以对它们运行流作业 I tried hadoop jar usr lib hadoop mapreduce had
  • Azure 发布管道,失败阶段后继续

    我有以下天蓝色发布管道 问题是 有时我需要离开左阶段才能失败 但同时 即使失败 右阶段仍然应该执行 这可能吗 我发现的唯一的事情是 即使所选阶段部分成功也会触发 但如果前一阶段失败 它就不起作用 有时我需要离开左阶段才能失败 但同时 即使失
  • 下载html源android?

    我正在尝试下载网站源代码并将其显示在文本框中 但我似乎收到错误并且无法弄清楚 s public void getHtml throws ClientProtocolException IOException HttpClient httpC
  • 单击开始按钮时的 JavaScript 倒计时器,显示小时、分钟和秒

    我想在单击按钮时创建小时 分钟和秒的倒计时器 这是我到目前为止的代码 HTMLcode div class colomn style margin right 20px div
  • 是否可以制作一个调用 jdbc 的 Java JNI?

    我是 jni 的新手 并且非常困惑是否可以使用 jni 来实现我需要完成的任务 我想制作一个java api 它将使用jdbc来更新数据库 但是这个特定的api将从C 程序中调用 所以我想我可能应该编写通过 jdbc 访问数据库的 jni