JAVA一分钟游戏编程-游戏库改造之JNA(08)

1.目标

一分钟实现游戏库改造之JNA

2.JNA调用

2.1 JNA调用C++库

上一节我们写了一个简单的JNI调用,步骤显得相当繁琐。

而且我们之前提到过,目的是要跨语言(不仅Java使用,Python和Lua也能使用),JNI直接调用方式引入了jdk下的jni相关头文件,这种方式侵入了C++源代码,就达不到初衷了。

为了更简单的调用本地库,而且不让JNI逻辑侵入C++,接下来我们使用JNA。

2.1.1 编译C++库

在使用JNA之前,我们移除原C++代码中的所有JNI相关头文件,重写编译一下C++库。

调整后,目录结构如下:

C++动态库如果要导出方法,则需要有宏定义__declspec(dllexport)

为了更好的被其他语言兼容使用,我们还需要加上extern "C"。extern "C"修饰的方法或模块会按照 C 语言的规则编译代码,确保方法名导出时不被更改。

让我们将hello方法的名称改成pineaInit,并修改代码:

// Pinea.h

#pragma once

// 条件预定义宏,如果定义了PINEA_BUILD_DLL则PINEA_API替换为 __declspec(dllexport)
#ifdef PINEA_BUILD_DLL
#define PINEA_API __declspec(dllexport)
#else
#define PINEA_API __declspec(dllimport)
#endif

extern "C" {
PINEA_API void pineaInit(const char* title, int width, int height);
}



// Pinea.cpp
#include "Pinea.h"
#include <iostream>

void pineaInit() {
    // 简单打印
    std::cout << "Hello Pinea!" << std::endl;
}

接着,在CMakeLists.txt中添加预定义宏PINEA_BUILD_DLL:

保存代码并编译:

2.1.2 引入JNA依赖

在pom.xml引入jna的maven依赖:

<dependencies>
	<dependency>
		<groupId>net.java.dev.jna</groupId>
		<artifactId>jna</artifactId>
		<version>5.13.0</version>
	</dependency>
</dependencies>

2.1.3 定义Native方法

定义Pinea接口继承Library:

import com.sun.jna.Library;

public interface Pinea extends Library {
    void pineaInit();
}

2.1.4 调用动态库

通过JNA调用本地方法前,我们需要先设置JNA要加载库的目录及库名称:

运行后,控制台打印正常,相当完美。

3.中章

邪宗C/C++不知名结界处。

张平安大手一挥,伴随着金光闪烁,一颗约莫拳头大小的水晶珠子从他的袖口飞出,骤然止于结界光幕半尺之处。

水晶珠子悬于半空,表面流光溢彩,一眼看去便知不凡。

张平安双目微凝,指尖在身前飞快捻转,嘴唇开合间,似有晦涩咒文断续传出,每一段咒文都带着灵力震颤,让周围空间都跟着颤动起来。

“编译C++为动态库;”

“设置JNA库加载目录,加载本地库;”

“调用本地方法;”

“……”

“妈妈咪咪哄,开!”

随着张平安一声大喝,半空的水晶珠子仿若有所感应,“砰”的一生爆开,化为点点零星附于结界光幕上,但这些零星并没有消失,而是在光幕上缓缓汇聚,形成某种玄妙的纹路。

王富贵抬头看去,满脸惊叹:“终于要打开结界通道了吗,JNA符宝果真名不虚传啊!”

片刻后,半空中的结界光幕破开一个人形大小的洞口。

王富贵和张平安相互对视一眼,没有犹豫,纷纷闪进洞口,进入了C/C++上古邪宗。

入宗后,一阵天旋地转。

好半晌,两人才恢复过来,还没来得及松一口气,各自脸上皆是充满震惊。

四周天昏地暗,空气中弥漫着一层诡异的红雾,呼吸间更是有着阵阵阴寒之意袭来,那种寒意侵入肺腑,令得浑身不自觉地颤栗。

“这里果然邪门!”

两人立即开启金光护盾,每迈出一步都小心翼翼,犹如摸着石头过河。

就在这时,蓦地从身后传来了一道熟悉的声音。

“王师兄,张师兄,你们两也来这里了?”

“是李师弟。”

两人惊喜回头,只见李吉祥正立于不远处,两团诡异的黑气缭绕在他周身,在其眼中,竟是有着骇人红芒不断闪烁。

“皇天不负有心人,探索这么多年了,我终于得偿所愿。”

李吉祥微微抬手,刹那间,一把漆黑细长的锻刀显现而出,刀身处,竟是龙飞凤舞雕刻着几个醒目的Ascii码:

“S - D - L - 3!”

……

4.SDL3初探

4.1 SDL3环境

4.1.1 下载库

SDL3库

SDL3Image库

4.1.2 添加库

将SDL3和SDL3Image相关头文件和库添加到csrc,目录结构如下:

修改CMakeLists.txt配置,添加lib:

Pinea.cpp引入了SDL3的头文件,编译测试一下环境的正确性:

4.2 SDL3显示窗口

之前,我们起步于Swing创建窗口,现在,我们的第一步依然是用SDL3创建一个窗口:

void pineaInit() {
    SDL_Init(SDL_INIT_VIDEO);
    SDL_Window *window = SDL_CreateWindow("Pinea", 800, 600, 0);
    SDL_Event event;
    bool running = true;
    while (running) {
        while (SDL_PollEvent(&event)) {
            if (event.type == SDL_EVENT_QUIT) {
                running = false;
            }
        }
    }
    SDL_DestroyWindow(window);
    SDL_Quit();
}

如果你已经封装过Pinea库,这段代码一定很熟悉了:创建一个窗口,不停地获取事件判断是否退出,以及最后删除窗口终止程序

保存代码后编译,没有任何问题。我们不用修改任何Java代码,直接启动Java程序,屏幕上便出现一个黑色的窗口啦!

6.思考:如何通过JNA的方式绑定SDL3呢?

我们已经能够使用JNA的方式调用C++库了,也初步了解了SDL3是什么,如何将这两者结合起来,实现类似我们之前Pinea库呢?

欢迎继续关注《JAVA一分钟游戏编程系列》,下期不见不散。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值